home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / midi / mp_1_0 / part01 next >
Encoding:
Internet Message Format  |  1991-03-15  |  70.4 KB

  1. Path: news.larc.nasa.gov!amiga-request
  2. From: amiga-request@ab20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v91i064: MP 1.0 - the MIDI Playground, Part01/02
  4. Reply-To: barrett@server.cs.jhu.edu
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v91i064@ab20.larc.nasa.gov>
  7. Date: 15 Mar 91 19:25:16 GMT
  8. Approved: tadguy@uunet.UU.NET (Tad Guy)
  9. X-Mail-Submissions-To: amiga@uunet.uu.net
  10. X-Post-Discussions-To: comp.sys.amiga.misc
  11.  
  12. Submitted-by: barrett@server.cs.jhu.edu
  13. Posting-number: Volume 91, Issue 064
  14. Archive-name: midi/mp-1.0/part01
  15.  
  16. [ includes uuencoded executable  ...tad ]
  17.  
  18.     This is a submission for comp.sources.amiga, entitled "MIDI
  19. Playground", written by me.  It's a versatile utility for making your Amiga
  20. communicate with a MIDI instrument.  It's helpful for learning about MIDI,
  21. designing MIDI software, and other related tasks.
  22.  
  23.     Uuencoded binary is included.
  24.  
  25.                                                         Dan
  26.  
  27. #!/bin/sh
  28. # This is a shell archive.  Remove anything before this line, then unpack
  29. # it by saving it into a file and typing "sh file".  To overwrite existing
  30. # files, type "sh file -c".  You can also feed this as standard input via
  31. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  32. # will see the following message at the end:
  33. #        "End of archive 1 (of 2)."
  34. # Contents:  CONTENTS Examples Examples.DOC Examples/CHORD-OFF
  35. #   Examples/CHORD-ON Examples/DISPLAY-FUN README Scripts
  36. #   Scripts/Converse Scripts/PatchChange Scripts/Text2Midi
  37. #   Scripts/TwoWindows Source Source/Makefile Source/amigados.c
  38. #   Source/cli.c Source/files.c Source/getopt.c Source/help.c
  39. #   Source/iofunctions.c Source/main.c Source/midi.h Source/mp.h
  40. #   Source/serial.c Source/text.c Source/version.h Source/wb.c
  41. # Wrapped by tadguy@ab20 on Fri Mar 15 14:25:13 1991
  42. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  43. if test -f 'CONTENTS' -a "${1}" != "-c" ; then 
  44.   echo shar: Will not clobber existing file \"'CONTENTS'\"
  45. else
  46. echo shar: Extracting \"'CONTENTS'\" \(353 characters\)
  47. sed "s/^X//" >'CONTENTS' <<'END_OF_FILE'
  48. XMIDI_Playground    A small, useful utility for sending any MIDI data back and
  49. X        forth between an Amiga and a MIDI instrument.  Helpful for
  50. X        learning about MIDI, writing/debugging MIDI software,
  51. X        figuring out your instrument's system-exclusive
  52. X        implementation, and more.  Very versatile.  Version 1.0,
  53. X        includes source.
  54. X        Author:  Daniel J. Barrett
  55. X            
  56. END_OF_FILE
  57. if test 353 -ne `wc -c <'CONTENTS'`; then
  58.     echo shar: \"'CONTENTS'\" unpacked with wrong size!
  59. fi
  60. # end of 'CONTENTS'
  61. fi
  62. if test ! -d 'Examples' ; then
  63.     echo shar: Creating directory \"'Examples'\"
  64.     mkdir 'Examples'
  65. fi
  66. if test -f 'Examples.DOC' -a "${1}" != "-c" ; then 
  67.   echo shar: Will not clobber existing file \"'Examples.DOC'\"
  68. else
  69. echo shar: Extracting \"'Examples.DOC'\" \(907 characters\)
  70. sed "s/^X//" >'Examples.DOC' <<'END_OF_FILE'
  71. XRead MP.DOC before you read this file.
  72. X
  73. XMP is very flexible because:
  74. X
  75. X    o    It can translate between 3 kinds of data formats:
  76. X
  77. X        -    Text.
  78. X        -    Binary data.
  79. X        -    MIDI data.
  80. X
  81. X    o    The input/output can be sent to/from:
  82. X
  83. X        -    Your CLI window.
  84. X        -    Files, using -g and -p.
  85. X        -    Files, using the CLI redirection symbols "<" and
  86. X            ">".
  87. X        -    Newly-created windows, by specifying a file
  88. X            name like "CON:0/0/640/100/MP Input".
  89. X        -    The MIDI port.
  90. X
  91. XMP does not have a window/mouse/icon graphic interface; instead, YOU
  92. Xdesign the interface using CLI scripts.  See the "Scripts" directory
  93. Xfor some small examples.  You can use MP in AREXX scripts too.
  94. X
  95. XFor a Workbench interface, use the IconX program (supplied with your
  96. XAmiga) to attach an icon to a CLI script.  Then fill the CLI script
  97. Xwith MP commands.
  98. X
  99. XThe directory "Examples" has some sample files that use the input
  100. Xtext language.  You can send them to your synthesizer.
  101. END_OF_FILE
  102. if test 907 -ne `wc -c <'Examples.DOC'`; then
  103.     echo shar: \"'Examples.DOC'\" unpacked with wrong size!
  104. fi
  105. # end of 'Examples.DOC'
  106. fi
  107. if test -f 'Examples/CHORD-OFF' -a "${1}" != "-c" ; then 
  108.   echo shar: Will not clobber existing file \"'Examples/CHORD-OFF'\"
  109. else
  110. echo shar: Extracting \"'Examples/CHORD-OFF'\" \(72 characters\)
  111. sed "s/^X//" >'Examples/CHORD-OFF' <<'END_OF_FILE'
  112. X; Cease playing a C major triad on MIDI channel 0.
  113. X
  114. X0x90 60 0 64 0 67 0
  115. END_OF_FILE
  116. if test 72 -ne `wc -c <'Examples/CHORD-OFF'`; then
  117.     echo shar: \"'Examples/CHORD-OFF'\" unpacked with wrong size!
  118. fi
  119. # end of 'Examples/CHORD-OFF'
  120. fi
  121. if test -f 'Examples/CHORD-ON' -a "${1}" != "-c" ; then 
  122.   echo shar: Will not clobber existing file \"'Examples/CHORD-ON'\"
  123. else
  124. echo shar: Extracting \"'Examples/CHORD-ON'\" \(69 characters\)
  125. sed "s/^X//" >'Examples/CHORD-ON' <<'END_OF_FILE'
  126. X; Play a C major triad on MIDI channel 0.
  127. X
  128. X0x90 60 127 64 127 67 127
  129. END_OF_FILE
  130. if test 69 -ne `wc -c <'Examples/CHORD-ON'`; then
  131.     echo shar: \"'Examples/CHORD-ON'\" unpacked with wrong size!
  132. fi
  133. # end of 'Examples/CHORD-ON'
  134. fi
  135. if test -f 'Examples/DISPLAY-FUN' -a "${1}" != "-c" ; then 
  136.   echo shar: Will not clobber existing file \"'Examples/DISPLAY-FUN'\"
  137. else
  138. echo shar: Extracting \"'Examples/DISPLAY-FUN'\" \(340 characters\)
  139. sed "s/^X//" >'Examples/DISPLAY-FUN' <<'END_OF_FILE'
  140. X; An example of sending text to the Matrix-12 display.
  141. X; Xpander users must change the 4th byte to 0x05.
  142. X; You MUST send exactly 80 characters or the Oberheim ignores you.
  143. X; Send this with:
  144. X;    mp  -g  DISPLAY-FUN  -it  -om 
  145. X
  146. X0xf0 0x10 0x02 0x06 0x01
  147. X"I THINK THAT I SHALL NEVER SEE          "
  148. X"A POEM AS LOVELY AS LITTLE OL' ME       "
  149. X0xf7
  150. END_OF_FILE
  151. if test 340 -ne `wc -c <'Examples/DISPLAY-FUN'`; then
  152.     echo shar: \"'Examples/DISPLAY-FUN'\" unpacked with wrong size!
  153. fi
  154. # end of 'Examples/DISPLAY-FUN'
  155. fi
  156. if test -f 'README' -a "${1}" != "-c" ; then 
  157.   echo shar: Will not clobber existing file \"'README'\"
  158. else
  159. echo shar: Extracting \"'README'\" \(461 characters\)
  160. sed "s/^X//" >'README' <<'END_OF_FILE'
  161. XMP:        A MIDI Playground
  162. XAuthor:        Daniel J. Barrett, barrett@cs.jhu.edu.
  163. XNo Copyright:    100% Public Domain.
  164. X        Please share this program with others.
  165. X
  166. X    MP is a small program that lets your Amiga communicate with a
  167. XMIDI instrument.  It runs from the CLI only (but can be made to run
  168. Xfrom the Workbench by using "IconX").
  169. X
  170. XSee the file MP.DOC for full instructions on how to use this program.
  171. XSee EXAMPLES.DOC for information about the supplied examples and scripts.
  172. END_OF_FILE
  173. if test 461 -ne `wc -c <'README'`; then
  174.     echo shar: \"'README'\" unpacked with wrong size!
  175. fi
  176. # end of 'README'
  177. fi
  178. if test ! -d 'Scripts' ; then
  179.     echo shar: Creating directory \"'Scripts'\"
  180.     mkdir 'Scripts'
  181. fi
  182. if test -f 'Scripts/Converse' -a "${1}" != "-c" ; then 
  183.   echo shar: Will not clobber existing file \"'Scripts/Converse'\"
  184. else
  185. echo shar: Extracting \"'Scripts/Converse'\" \(151 characters\)
  186. sed "s/^X//" >'Scripts/Converse' <<'END_OF_FILE'
  187. Xrun <NIL: >NIL: mp -it -om -g "CON:0/1/640/75/Send MIDI; end with ^\"
  188. Xwait 1
  189. Xrun <NIL: >NIL: mp -im -ot -p "CON:0/76/640/75/Receive MIDI; end with ^C"
  190. END_OF_FILE
  191. if test 151 -ne `wc -c <'Scripts/Converse'`; then
  192.     echo shar: \"'Scripts/Converse'\" unpacked with wrong size!
  193. fi
  194. # end of 'Scripts/Converse'
  195. fi
  196. if test -f 'Scripts/PatchChange' -a "${1}" != "-c" ; then 
  197.   echo shar: Will not clobber existing file \"'Scripts/PatchChange'\"
  198. else
  199. echo shar: Extracting \"'Scripts/PatchChange'\" \(172 characters\)
  200. sed "s/^X//" >'Scripts/PatchChange' <<'END_OF_FILE'
  201. X.KEY patchnum/a
  202. X.BRA {
  203. X.KET }
  204. X
  205. Xecho "Changing to patch {patchnum} on MIDI channel 0..."
  206. Xecho > pipe:patchchange "0xC0 {patchnum}"
  207. Xmp -it -om -g pipe:patchchange
  208. Xecho Done!
  209. END_OF_FILE
  210. if test 172 -ne `wc -c <'Scripts/PatchChange'`; then
  211.     echo shar: \"'Scripts/PatchChange'\" unpacked with wrong size!
  212. fi
  213. # end of 'Scripts/PatchChange'
  214. fi
  215. if test -f 'Scripts/Text2Midi' -a "${1}" != "-c" ; then 
  216.   echo shar: Will not clobber existing file \"'Scripts/Text2Midi'\"
  217. else
  218. echo shar: Extracting \"'Scripts/Text2Midi'\" \(137 characters\)
  219. sed "s/^X//" >'Scripts/Text2Midi' <<'END_OF_FILE'
  220. X.KEY TextFile/a
  221. X.BRA {
  222. X.KET }
  223. X
  224. Xecho "Converting {TextFile} to {TextFile}.midi..."
  225. Xmp -it -ob -g {TextFile} -p {TextFile}.midi
  226. Xecho Done!
  227. END_OF_FILE
  228. if test 137 -ne `wc -c <'Scripts/Text2Midi'`; then
  229.     echo shar: \"'Scripts/Text2Midi'\" unpacked with wrong size!
  230. fi
  231. # end of 'Scripts/Text2Midi'
  232. fi
  233. if test -f 'Scripts/TwoWindows' -a "${1}" != "-c" ; then 
  234.   echo shar: Will not clobber existing file \"'Scripts/TwoWindows'\"
  235. else
  236. echo shar: Extracting \"'Scripts/TwoWindows'\" \(107 characters\)
  237. sed "s/^X//" >'Scripts/TwoWindows' <<'END_OF_FILE'
  238. Xmp -it -ot -g "CON:0/1/640/75/Type commands Here..." -p "CON:0/76/640/75/...and watch them come out here!"
  239. END_OF_FILE
  240. if test 107 -ne `wc -c <'Scripts/TwoWindows'`; then
  241.     echo shar: \"'Scripts/TwoWindows'\" unpacked with wrong size!
  242. fi
  243. # end of 'Scripts/TwoWindows'
  244. fi
  245. if test ! -d 'Source' ; then
  246.     echo shar: Creating directory \"'Source'\"
  247.     mkdir 'Source'
  248. fi
  249. if test -f 'Source/Makefile' -a "${1}" != "-c" ; then 
  250.   echo shar: Will not clobber existing file \"'Source/Makefile'\"
  251. else
  252. echo shar: Extracting \"'Source/Makefile'\" \(2707 characters\)
  253. sed "s/^X//" >'Source/Makefile' <<'END_OF_FILE'
  254. X###########################################################################
  255. X# Makefile:    Makefile for Manx Aztec C, version 5.0.
  256. X#        Part of MP, the MIDI Playground.
  257. X#
  258. X# Author:    Daniel Barrett
  259. X# Version:    See the file "version.h".
  260. X# Copyright:    None!  This program is in the Public Domain.
  261. X#        Please share it with others.
  262. X###########################################################################
  263. X
  264. X    
  265. XOPTIMIZE    = -so
  266. XDEBUGGING    = #-bs
  267. XLDEBUGGING    = #-g
  268. X    
  269. XLFLAGS        = $(LDEBUGGING) +Q
  270. XCFLAGS          = $(OPTIMIZE) -hi $(COMP_INC) $(DEBUGGING)
  271. XLIBS        = -lc
  272. XCOMP_INC    = headers.comp
  273. XLIBS        = -lc
  274. X
  275. XBACKUPDIR    = df1:sysex
  276. X    
  277. X##############################################################################
  278. X# Files used for all programs.
  279. X##############################################################################
  280. X
  281. XPROG        = mp
  282. XMAINHEADER    = mp.h
  283. XHEADERS        = $(MAINHEADER) version.h midi.h
  284. XSRC        = text.c main.c serial.c getopt.c iofunctions.c help.c \
  285. X          files.c wb.c cli.c amigados.c
  286. XOBJ        = text.o main.o serial.o getopt.o iofunctions.o help.o \
  287. X          files.o wb.o cli.o amigados.o
  288. X
  289. X##############################################################################
  290. X# The program.
  291. X##############################################################################
  292. X
  293. X$(PROG):    $(COMP_INC) $(OBJ)
  294. X        @echo ""
  295. X        @echo "Ignore messages about _abort overriding library."
  296. X        @echo ""
  297. X        ln $(LFLAGS) $(OBJ) -o $(PROG) $(LIBS)
  298. X
  299. X$(OBJ):        $(MAINHEADER)
  300. X
  301. X##############################################################################
  302. X# Individual dependencies.
  303. X##############################################################################
  304. X
  305. Xhelp.o:        help.c        $(MAINHEADER) version.h
  306. Xiofunctions.o:    iofunctions.c $(MAINHEADER) midi.h
  307. Xserial.o:    serial.c      $(MAINHEADER) midi.h
  308. X    
  309. X##############################################################################
  310. X# Compiled headers.
  311. X##############################################################################
  312. X
  313. X$(COMP_INC):    $(MAINHEADER)
  314. X        @echo "Compiling headers because of $?"
  315. X        cc $(OPTIMIZE) $(DEBUGGING) -ho $(COMP_INC) $(MAINHEADER)
  316. X
  317. X#$(MAINHEADER):    $(HEADERS)
  318. X
  319. X##############################################################################
  320. X# Clean up
  321. X##############################################################################
  322. X
  323. Xclean:
  324. X        delete \#?.o \#?.pro
  325. X
  326. Xveryclean:    clean
  327. X        delete $(COMP_INC) $(PROG) \#?.dbg
  328. X
  329. Xcbackup:
  330. X        copy \#?.c $(BACKUPDIR)
  331. X        copy \#?.h $(BACKUPDIR)
  332. X        copy Makefile $(BACKUPDIR)
  333. X
  334. Xbackup:        cbackup
  335. X        copy README $(BACKUPDIR)
  336. X        copy \#?.DOC $(BACKUPDIR)
  337. X        copy Scripts $(BACKUPDIR)/Scripts   all
  338. X        copy Examples $(BACKUPDIR)/Examples all
  339. X
  340. Xzoo:        $(PROG)
  341. X        delete ram:mp.zoo quiet
  342. X        zoo a ram:mp.zoo Source/* Scripts/* Examples/* \
  343. X                 $(PROG) *.DOC README Makefile
  344. END_OF_FILE
  345. if test 2707 -ne `wc -c <'Source/Makefile'`; then
  346.     echo shar: \"'Source/Makefile'\" unpacked with wrong size!
  347. fi
  348. # end of 'Source/Makefile'
  349. fi
  350. if test -f 'Source/amigados.c' -a "${1}" != "-c" ; then 
  351.   echo shar: Will not clobber existing file \"'Source/amigados.c'\"
  352. else
  353. echo shar: Extracting \"'Source/amigados.c'\" \(1684 characters\)
  354. sed "s/^X//" >'Source/amigados.c' <<'END_OF_FILE'
  355. X/**************************************************************************
  356. X* amigados.c:    Requestor and Environment Variable routines.
  357. X*        Part of MP, the MIDI Playground.
  358. X*
  359. X* Author:    Daniel Barrett
  360. X* Version:    See the file "version.h".
  361. X* Copyright:    None!  This program is in the Public Domain.
  362. X*        Please share it with others.
  363. X***************************************************************************/
  364. X
  365. X    
  366. X#include <exec/types.h>
  367. X#include <stdlib.h>
  368. X#include <functions.h>
  369. X#include <libraries/dos.h>
  370. X#include <libraries/dosextens.h>
  371. X
  372. X    
  373. Xvoid DisableRequestors(void);
  374. Xvoid EnableRequestors(void);
  375. X
  376. X    
  377. X#define    ENV_NAME_LENGTH        BUFSIZ
  378. X
  379. X    
  380. X/* Return the value of ENV: environment variable "variableName", if it
  381. X * exists.   We use this instead of the built-in getenv() because we
  382. X * want to turn off requestors during the search for ENV:, in case it
  383. X * is not mounted. */
  384. X
  385. Xchar *GetEnv(char *variableName)
  386. X{
  387. X    char *result;
  388. X
  389. X    DisableRequestors();        /* In case ENV: is non-existent. */
  390. X    result = getenv(variableName);
  391. X    EnableRequestors();
  392. X    return(result);
  393. X}
  394. X
  395. X
  396. X/***************************************************************************
  397. X* Deal with requestors.
  398. X***************************************************************************/
  399. X
  400. Xstatic APTR oldWindowPtr;
  401. Xstatic struct Process *theProc;
  402. X
  403. X/* Turn off system requestors for this process. */
  404. X
  405. Xvoid DisableRequestors(void)
  406. X{
  407. X    theProc = (struct Process *)FindTask(NULL);
  408. X    oldWindowPtr = theProc->pr_WindowPtr;
  409. X    theProc->pr_WindowPtr = (APTR)(-1L);
  410. X}
  411. X
  412. X
  413. X/* Turn on system requestors for this process, after they have been
  414. X * turned off by DisableRequestors(), above. */
  415. X
  416. Xvoid EnableRequestors(void)
  417. X{
  418. X    theProc->pr_WindowPtr = oldWindowPtr;
  419. X}
  420. END_OF_FILE
  421. if test 1684 -ne `wc -c <'Source/amigados.c'`; then
  422.     echo shar: \"'Source/amigados.c'\" unpacked with wrong size!
  423. fi
  424. # end of 'Source/amigados.c'
  425. fi
  426. if test -f 'Source/cli.c' -a "${1}" != "-c" ; then 
  427.   echo shar: Will not clobber existing file \"'Source/cli.c'\"
  428. else
  429. echo shar: Extracting \"'Source/cli.c'\" \(2379 characters\)
  430. sed "s/^X//" >'Source/cli.c' <<'END_OF_FILE'
  431. X/**************************************************************************
  432. X* cli.c:    The command-line interface for MP.
  433. X*        Part of MP, the MIDI Playground.
  434. X*
  435. X* Author:    Daniel Barrett
  436. X* Version:    See the file "version.h".
  437. X* Copyright:    None!  This program is in the Public Domain.
  438. X*        Please share it with others.
  439. X***************************************************************************/
  440. X
  441. X    
  442. X#include "mp.h"
  443. X
  444. X
  445. X/* The main program from the CLI.  Check the command-line arguments, set
  446. X * up the input and output files, and call MIDIPlayground(). */
  447. X    
  448. XBOOL CommandLineProgram(int argc, char *argv[])
  449. X{
  450. X    FILE *in, *out;
  451. X    char *infile, *outfile;
  452. X    FLAGS theFlags[NUM_FLAGS];
  453. X    
  454. X    InitStuff(theFlags, &in, &out, &infile, &outfile);
  455. X
  456. X    if ((argc == 1)   ||   (argc == 2 && !strcmp(argv[1], "?")))
  457. X        Help(argv[0]);
  458. X    else if (!HandleOptions(argc, argv, theFlags, &infile, &outfile))
  459. X    {
  460. X        fprintf(stderr, "There is an error in your options/flags.\n");
  461. X        BegForUsage(argv[0]);
  462. X    }
  463. X    else if (!SetupFiles(infile, outfile, &in, &out))
  464. X        ;
  465. X    else if (optind < argc)
  466. X    {
  467. X        fprintf(stderr, "You gave me too many arguments.\n");
  468. X        BegForUsage(argv[0]);
  469. X    }
  470. X    else
  471. X        (void)MIDIPlayground(theFlags, in, out);
  472. X
  473. X    CloseFiles(in, out, infile, outfile);
  474. X}
  475. X
  476. X    
  477. X/************************************************************************
  478. X* Handling command-line options.
  479. X************************************************************************/
  480. X
  481. XBOOL HandleOptions(int argc, char *argv[], FLAGS theFlags[], char **infile,
  482. X           char **outfile)
  483. X{
  484. X    int c;
  485. X    BOOL success = TRUE;
  486. X    static char options[] = GETOPT_OPTIONS;
  487. X    
  488. X    while ((c = getopt(argc, argv, options)) != EOF)
  489. X    {
  490. X        switch (c)
  491. X        {
  492. X          case OPT_INPUT:
  493. X             success &= !theFlags[FLAG_ITYPE];
  494. X             success &= CheckIOType(*optarg, FLAG_ITYPE, theFlags);
  495. X             break;
  496. X          case OPT_OUTPUT:
  497. X             success &= !theFlags[FLAG_OTYPE];
  498. X             success &= CheckIOType(*optarg, FLAG_OTYPE, theFlags);
  499. X             break;
  500. X          case OPT_INFILE:
  501. X             success &= (optarg[0] != '\0');
  502. X             success &= MakeFilename(infile, optarg);
  503. X             break;
  504. X          case OPT_OUTFILE:
  505. X             success &= (optarg[0] != '\0');
  506. X             success &= MakeFilename(outfile, optarg);
  507. X             break;
  508. X          case OPT_SYSEX:
  509. X             success &= !theFlags[FLAG_SYSEX];
  510. X             theFlags[FLAG_SYSEX]++;
  511. X             break;
  512. X          default:
  513. X             success = FALSE;
  514. X             break;
  515. X        }
  516. X    }
  517. X    return(success && CheckFlags(theFlags));
  518. X}
  519. X
  520. X    
  521. END_OF_FILE
  522. if test 2379 -ne `wc -c <'Source/cli.c'`; then
  523.     echo shar: \"'Source/cli.c'\" unpacked with wrong size!
  524. fi
  525. # end of 'Source/cli.c'
  526. fi
  527. if test -f 'Source/files.c' -a "${1}" != "-c" ; then 
  528.   echo shar: Will not clobber existing file \"'Source/files.c'\"
  529. else
  530. echo shar: Extracting \"'Source/files.c'\" \(3363 characters\)
  531. sed "s/^X//" >'Source/files.c' <<'END_OF_FILE'
  532. X/**************************************************************************
  533. X* files.c:    File open/close, input/output, etc.
  534. X*        Part of MP, the MIDI Playground.
  535. X*
  536. X* Author:    Daniel Barrett
  537. X* Version:    See the file "version.h".
  538. X* Copyright:    None!  This program is in the Public Domain.
  539. X*        Please share it with others.
  540. X***************************************************************************/
  541. X
  542. X    
  543. X#include <stdio.h>
  544. X#include <exec/types.h>
  545. X#include <libraries/dos.h>
  546. X#include <libraries/dosextens.h>
  547. X
  548. X
  549. X/* Open a file and return a pointer to it. */
  550. X    
  551. XFILE *OpenAFile(char *filename, char *mode, char *readOrWrite)
  552. X{
  553. X    FILE *fp;
  554. X
  555. X        if ((fp = fopen(filename, mode)) == NULL)
  556. X        fprintf(stderr, "Cannot %s the file \"%s\",\n",
  557. X            readOrWrite, filename);
  558. X    return(fp);
  559. X}
  560. X
  561. X    
  562. X/* Open a file for reading.  We might also have a macro with the same name,
  563. X * so we used ifdef's. */
  564. X
  565. X#ifndef OpenReadFile    
  566. XFILE *OpenReadFile(char *filename)
  567. X{
  568. X    return(OpenAFile(filename, "r", "read"));
  569. X}
  570. X#endif
  571. X
  572. X    
  573. X/* Open a file for writing.  We might also have a macro with the same name,
  574. X * so we used ifdef's. */
  575. X
  576. X#ifndef OpenWriteFile
  577. XFILE *OpenWriteFile(char *filename)
  578. X{
  579. X    return(OpenAFile(filename, "w", "write"));
  580. X}
  581. X#endif
  582. X
  583. X    
  584. X/* Tell me whether or not a file exists. */
  585. X
  586. XBOOL FileExists(char *filename)
  587. X{
  588. X    BPTR lock;
  589. X
  590. X    if ((lock = Lock(filename, ACCESS_READ)) != NULL)
  591. X    {
  592. X        UnLock(lock);
  593. X        return(TRUE);
  594. X    }
  595. X    return(FALSE);
  596. X}
  597. X
  598. X    
  599. X/* See if we want to overwrite an existing file. */
  600. X
  601. X/* BUFSIZ is too large, perhaps -- change later -- but don't compromise
  602. X * on correct reading of the user's input.  Too small, and extra unread
  603. X * chars are read on the NEXT call (yuck).  If you use gets(), too much
  604. X * input crashes the program. */
  605. X
  606. XBOOL DontOverwriteExistingFile(char *filename)
  607. X{
  608. X    char buf[BUFSIZ];
  609. X    BOOL safety = TRUE;
  610. X
  611. X    if (FileExists(filename))
  612. X    {
  613. X        fprintf(stderr,
  614. X             "File \"%s\" already exists.\nOVERWRITE it? [%s]: ",
  615. X             filename, "Yes/No, RETURN=No");
  616. X        fflush(stderr);
  617. X
  618. X        if (fgets(buf, BUFSIZ-1, stdin))
  619. X            safety = (toupper(buf[0]) != 'Y');
  620. X        else
  621. X            safety = TRUE;
  622. X    }
  623. X    else
  624. X        safety = FALSE;            /* File doesn't exist. */
  625. X
  626. X    if (safety)
  627. X        fprintf(stderr, "%s not overwritten.\n\n", filename);
  628. X
  629. X    return(safety);
  630. X}
  631. X
  632. X
  633. X/* Open the input and output files.
  634. X * We open input AFTER output in case the user has specified CON: windows,
  635. X * so the input window is the active one. */
  636. X
  637. XBOOL SetupFiles(char *infile, char *outfile, FILE **in, FILE **out)
  638. X{
  639. X    if (!outfile || (outfile[0] == '\0'))
  640. X        *out = stdout;
  641. X    else if (DontOverwriteExistingFile(outfile))
  642. X        return(FALSE);
  643. X    else if ((*out = OpenWriteFile(outfile)) == NULL)
  644. X        return(FALSE);
  645. X
  646. X    if (!infile || (infile[0] == '\0'))
  647. X        *in = stdin;
  648. X    else if ((*in = OpenReadFile(infile)) == NULL)
  649. X        return(FALSE);
  650. X
  651. X    return(TRUE);
  652. X}
  653. X
  654. X    
  655. X/* Close the files used by the program, and deallocate the arrays used
  656. X * for storing the filenames. */
  657. X
  658. Xvoid CloseFiles(FILE *in, FILE *out, char *filein, char *fileout)
  659. X{
  660. X    if (in && (in != stdin))    fclose(in);
  661. X    if (out && (out != stdout))    fclose(out);
  662. X    if (filein)            free(filein);
  663. X    if (fileout)            free(fileout);
  664. X}
  665. X
  666. X    
  667. X/* Allocate space to store a filename, and copy the contents of "src" into
  668. X * it. */
  669. X
  670. XBOOL MakeFilename(char **dest, char *src)
  671. X{
  672. X    if ((!src) || (*src == '\0')
  673. X    ||  ((*dest = (char *)malloc(strlen(src)+1)) == NULL))
  674. X        return(FALSE);
  675. X    else
  676. X    {
  677. X        strcpy(*dest, src);
  678. X        return(TRUE);
  679. X    }
  680. X}
  681. END_OF_FILE
  682. if test 3363 -ne `wc -c <'Source/files.c'`; then
  683.     echo shar: \"'Source/files.c'\" unpacked with wrong size!
  684. fi
  685. # end of 'Source/files.c'
  686. fi
  687. if test -f 'Source/getopt.c' -a "${1}" != "-c" ; then 
  688.   echo shar: Will not clobber existing file \"'Source/getopt.c'\"
  689. else
  690. echo shar: Extracting \"'Source/getopt.c'\" \(7295 characters\)
  691. sed "s/^X//" >'Source/getopt.c' <<'END_OF_FILE'
  692. X/****************************************************************************
  693. X * getopt():    Return the next user option on each iteration. 
  694. X *        This is a clone of the usual UNIX getopt() function.
  695. X *        If you have never used a getopt() before, you'll have to
  696. X *          read about it on any UNIX machine or other C system that
  697. X *          documents it.
  698. X *
  699. X * Author:    Daniel Barrett, barrett@cs.jhu.edu.
  700. X * Date:    February 20, 1991.
  701. X * Version:    1.1.
  702. X *
  703. X * License:    This code is placed in the Public Domain.
  704. X *        Give it away to anybody for free!
  705. X *        Use it for any purpose you like!
  706. X *
  707. X *        If you use this code in a program, please give me credit
  708. X *        for my work.  Thanks!
  709. X *
  710. X * Why I wrote it:
  711. X *
  712. X *        Because every other getopt() function I have ever seen
  713. X *         had source code that was difficult to understand.
  714. X *        I wrote this code to be very modular and readable.
  715. X *        I hope you find it instructive and/or helpful.
  716. X *
  717. X * REVISION HISTORY:
  718. X *    Version:    1.1
  719. X *    Date:        February 20, 1991.
  720. X *    Comments:    Bug fix in Pass().  Forgot to check that the
  721. X *            current argument is non-empty and starts with
  722. X *            a DASH.
  723. X *
  724. X *            Got rid of the unnecessary "g_" at the beginning
  725. X *            of each function name.  Since they're static, we
  726. X *            don't have to worry about duplication of names
  727. X *            by the calling program.
  728. X *
  729. X *    Version:    1.0
  730. X *    Date:        April 12, 1990.
  731. X *    Comments:    First released version.
  732. X *
  733. X ****************************************************************************/
  734. X
  735. X#ifndef __STDIO_H    /* If we haven't already included stdio.h, do it. */
  736. X#include <stdio.h>    /* Maybe someday I'll eliminate this. */
  737. X#endif
  738. X
  739. X/************************************************************************
  740. X* Some constants.
  741. X************************************************************************/
  742. X
  743. X#define    DASH        '-'    /* This preceeds an option. */
  744. X#define    ARG_COMING    ':'    /* In the option string, this indicates that
  745. X                 * that the option requires an argument. */
  746. X#define    UNKNOWN_OPT    '?'    /* The char returned for unknown option. */
  747. X
  748. X/************************************************************************
  749. X* Internal error codes.
  750. X************************************************************************/
  751. X
  752. X#define    ERROR_BAD_OPTION    1
  753. X#define    ERROR_MISSING_ARGUMENT    2
  754. X
  755. X/************************************************************************
  756. X* Mnemonic macros.
  757. X************************************************************************/
  758. X
  759. X
  760. X
  761. X/************************************************************************
  762. X* ANSI function prototypes.
  763. X************************************************************************/
  764. X
  765. Xint        getopt(int argc, char *argv[], char *optString);
  766. Xstatic int    NextOption(char *argv[], char *optString);
  767. Xstatic int    RealOption(char *argv[], char *str, int *skip, int *ind,
  768. X                 int opt);
  769. Xstatic void    HandleArgument(char *argv[], int *optind, int *skip);
  770. Xstatic void    Error(int err, int c);
  771. Xstatic void    Pass(char *argv[], int *optind, int *optsSkipped);
  772. X
  773. Xextern char    *index();
  774. X
  775. X/************************************************************************
  776. X* Global variables.  You must declare these externs in your program
  777. X* if you want to see their values!
  778. X************************************************************************/
  779. X    
  780. Xchar    *optarg    = NULL;    /* This will point to a required argument, if any. */
  781. Xint    optind    = 1;    /* The index of the next argument in argv. */
  782. Xint    opterr    = 1;    /* 1 == print internal error messages.  0 else. */
  783. Xint    optopt;        /* The actual option letter that was found. */
  784. X
  785. X
  786. Xint getopt(int argc, char *argv[], char *optString)
  787. X{
  788. X    optarg = NULL;
  789. X    if (optind < argc)        /* More arguments to check. */
  790. X        return(NextOption(argv, optString));
  791. X    else                /* We're done. */
  792. X        return(EOF);
  793. X}
  794. X
  795. X
  796. X/* If the current argument does not begin with DASH, it is not an option.
  797. X * Return EOF.
  798. X * If we have ONLY a DASH, and nothing after it... return EOF as well.
  799. X * If we have a DASH followed immediately by another DASH, this is the
  800. X * special "--" option that means "no more options follow."  Return EOF.
  801. X * Otherwise, we have an actual option or list of options.  Process it. */
  802. X    
  803. Xstatic int NextOption(char *argv[], char *optString)
  804. X{
  805. X    static int optsSkipped = 0;    /* In a single argv[i]. */
  806. X    
  807. X    if ((argv[optind][0] == DASH)
  808. X    &&  ((optopt = argv[optind][1+optsSkipped]) != '\0'))
  809. X    {
  810. X        if (optopt == DASH)
  811. X        {
  812. X            optind++;
  813. X            return(EOF);
  814. X        }
  815. X        else
  816. X            return(RealOption(argv, optString, &optsSkipped,
  817. X                        &optind, optopt));
  818. X    }
  819. X    else
  820. X        return(EOF);
  821. X}
  822. X
  823. X
  824. X/* At this point, we know that argv[optind] is an option or list of
  825. X * options.  If this is a list of options, *optsSkipped tells us how
  826. X * many of those options have ALREADY been parsed on previous calls
  827. X * to getopt().
  828. X * If the option is not legal (not in optString), complain and return
  829. X * UNKNOWN_OPT.
  830. X * If the option requires no argument, just return the option letter.
  831. X * If the option requires an argument, call HandleArgument and return
  832. X * the option letter. */
  833. X    
  834. Xstatic int RealOption(char *argv[], char *optString, int *optsSkipped,
  835. X            int *optind, int optopt)
  836. X{
  837. X    char *where;
  838. X
  839. X    (*optsSkipped)++;
  840. X    if (where = index(optString, optopt))
  841. X    {
  842. X        if (*(where+1) == ARG_COMING)
  843. X            HandleArgument(argv, optind, optsSkipped);
  844. X
  845. X        Pass(argv, optind, optsSkipped);
  846. X        return(optopt);
  847. X    }
  848. X    else
  849. X    {
  850. X        Error(ERROR_BAD_OPTION, optopt);
  851. X        Pass(argv, optind, optsSkipped);
  852. X        return(UNKNOWN_OPT);
  853. X    }
  854. X}
  855. X
  856. X
  857. X/* We have an option in argv[optind] that requires an argument.  If there
  858. X * is no whitespace after the option letter itself, take the rest of
  859. X * argv[optind] to be the argument.
  860. X * If there IS whitespace after the option letter, take argv[optind+1] to
  861. X * be the argument.
  862. X * Otherwise, if there is NO argument, complain! */
  863. X
  864. Xstatic void HandleArgument(char *argv[], int *optind, int *optsSkipped)
  865. X{
  866. X    if (argv[*optind][1+(*optsSkipped)])
  867. X        optarg = argv[*optind] + 1 + (*optsSkipped);
  868. X    else if (argv[(*optind)+1])
  869. X    {
  870. X        optarg = argv[(*optind)+1];
  871. X        (*optind)++;
  872. X    }
  873. X    else
  874. X        Error(ERROR_MISSING_ARGUMENT, optopt);
  875. X
  876. X    (*optsSkipped) = 0;
  877. X    (*optind)++;
  878. X}
  879. X
  880. X
  881. X/* Print an appropriate error message. */
  882. X
  883. Xstatic void Error(int err, int c)
  884. X{
  885. X    static char *optmsg = "Illegal option.\n";
  886. X    static char *argmsg = "An argument is required, but missing.\n";
  887. X
  888. X    if (opterr)
  889. X    {
  890. X        if (err == ERROR_BAD_OPTION)
  891. X            fprintf(stderr, "-%c: %s", c, optmsg);
  892. X        else if (err == ERROR_MISSING_ARGUMENT)
  893. X            fprintf(stderr, "-%c: %s", c, argmsg);
  894. X
  895. X        else    /* Sanity check! */
  896. X            fprintf(stderr, "-%c: an unknown error occurred\n",
  897. X                c);
  898. X    }
  899. X}
  900. X
  901. X
  902. X/* We have reached the end of argv[optind]... there are no more options
  903. X * in it to parse.  Skip to the next item in argv. */
  904. X
  905. Xstatic void Pass(char *argv[], int *optind, int *optsSkipped)
  906. X{
  907. X    if (argv[*optind]
  908. X    &&  (argv[*optind][0] == DASH)
  909. X    &&  (argv[*optind][1+(*optsSkipped)] == NULL))
  910. X    {
  911. X        (*optind)++;
  912. X        (*optsSkipped) = 0;
  913. X    }
  914. X}
  915. X
  916. X/***************************************************************************
  917. X* A test program.  Compile this file with -DTESTME as an option.
  918. X***************************************************************************/
  919. X
  920. X#ifdef TESTME
  921. Xmain(int argc, char *argv[])
  922. X{
  923. X    char c;
  924. X
  925. X    while ((c = getopt(argc, argv, "a:b:cde")) != EOF)
  926. X        {
  927. X        printf("OPTION %c", c);
  928. X        if ((c == 'a') || (c == 'b'))
  929. X            printf(", %s\n", optarg);
  930. X        else
  931. X            printf("\n");
  932. X        printf("argc=%d, optind=%d\n", argc, optind);
  933. X    }
  934. X    exit(0);
  935. X}
  936. X#endif
  937. END_OF_FILE
  938. if test 7295 -ne `wc -c <'Source/getopt.c'`; then
  939.     echo shar: \"'Source/getopt.c'\" unpacked with wrong size!
  940. fi
  941. # end of 'Source/getopt.c'
  942. fi
  943. if test -f 'Source/help.c' -a "${1}" != "-c" ; then 
  944.   echo shar: Will not clobber existing file \"'Source/help.c'\"
  945. else
  946. echo shar: Extracting \"'Source/help.c'\" \(2340 characters\)
  947. sed "s/^X//" >'Source/help.c' <<'END_OF_FILE'
  948. X/**************************************************************************
  949. X* help.c:    Functions for giving help to the user.
  950. X*        Part of MP, the MIDI Playground.
  951. X*
  952. X* Author:    Daniel Barrett
  953. X* Version:    See the file "version.h".
  954. X* Copyright:    None!  This program is in the Public Domain.
  955. X*        Please share it with others.
  956. X***************************************************************************/
  957. X
  958. X    
  959. X#include "mp.h"
  960. X#include "version.h"
  961. X
  962. X    
  963. X/* Print a detailed help message. */
  964. X
  965. Xvoid Help(char *progName)
  966. X{
  967. X    FILE *fp = stderr;
  968. X
  969. X    fprintf(fp, "MIDI Playground (%s), version %s, by Daniel Barrett."
  970. X            "  100%% Public Domain!\n",
  971. X        progName, VERSION);
  972. X    fprintf(fp,
  973. X       "Usage: %s -%c<FORMAT> -%c<FORMAT> [-%c infile] [-%c outfile]\n",
  974. X       progName,
  975. X       OPT_INPUT, OPT_OUTPUT, OPT_INFILE, OPT_OUTFILE);
  976. X
  977. X    fprintf(fp,
  978. X        "The program quits at end-of-file, or when ^C is pressed.\n");
  979. X
  980. X    fprintf(fp, "\nThe flags may appear in any order:\n");
  981. X    fprintf(fp, "\t-%c\tSpecify the input format.   [MANDATORY]\n",
  982. X        OPT_INPUT);
  983. X    fprintf(fp, "\t-%c\tSpecify the output format.  [MANDATORY]\n",
  984. X        OPT_OUTPUT);
  985. X    fprintf(fp, "\t\t\"-%c\" and \"-%c\" must EACH be followed by",
  986. X        OPT_INPUT, OPT_OUTPUT);
  987. X    fprintf(fp, " exactly one of:\n");
  988. X    fprintf(fp, "\t\t\t%c\tText (readable by humans).\n", OPT_TEXT);
  989. X    fprintf(fp, "\t\t\t%c\tBinary data (for files).\n", OPT_BINARY);
  990. X    fprintf(fp, "\t\t\t%c\tMIDI (using MIDI port).\n", OPT_MIDI);
  991. X    fprintf(fp, "\t-%c\tGet data from this file.    [Default=keyboard]\n",
  992. X        OPT_INFILE);
  993. X    fprintf(fp, "\t-%c\tPut data into this file.    [Default=screen]\n",
  994. X        OPT_OUTFILE);
  995. X
  996. X    fprintf(fp, "\nExamples:\n");
  997. X    fprintf(fp, "\t%s -%c%c -%c%c -%c data\t%s\n",
  998. X        progName,
  999. X        OPT_INPUT, OPT_MIDI, OPT_OUTPUT, OPT_BINARY,
  1000. X        OPT_OUTFILE,
  1001. X        "Read MIDI & put it into binary file \"data\".");
  1002. X    fprintf(fp,
  1003. X        "\t%s -%c%c -%c%c\t\tRead typed text, send to MIDI (fun!).\n",
  1004. X        progName,
  1005. X        OPT_INPUT, OPT_TEXT, OPT_OUTPUT, OPT_MIDI);
  1006. X
  1007. X    fprintf(fp, "\n\"%s -%c%c\" understands decimal, octal, hex,",
  1008. X        progName, OPT_INPUT, OPT_TEXT);
  1009. X    fprintf(fp, " binary, characters, and strings.\n");
  1010. X    fprintf(fp, "For details, type %c while in \"-%c%c\" mode.\n",
  1011. X        HELP_SYMBOL, OPT_INPUT, OPT_TEXT);
  1012. X}
  1013. X
  1014. X    
  1015. X/* Tell the user how to get more help. */
  1016. X
  1017. Xvoid BegForUsage(char *progName)
  1018. X{
  1019. X    fprintf(stderr, "Please type \"%s ?\" for instructions.\n",
  1020. X        progName);
  1021. X}
  1022. END_OF_FILE
  1023. if test 2340 -ne `wc -c <'Source/help.c'`; then
  1024.     echo shar: \"'Source/help.c'\" unpacked with wrong size!
  1025. fi
  1026. # end of 'Source/help.c'
  1027. fi
  1028. if test -f 'Source/iofunctions.c' -a "${1}" != "-c" ; then 
  1029.   echo shar: Will not clobber existing file \"'Source/iofunctions.c'\"
  1030. else
  1031. echo shar: Extracting \"'Source/iofunctions.c'\" \(3430 characters\)
  1032. sed "s/^X//" >'Source/iofunctions.c' <<'END_OF_FILE'
  1033. X/**************************************************************************
  1034. X* iofunctions.c:
  1035. X*        Functions for input/output in a variety of formats.    
  1036. X*        Part of MP, the MIDI Playground.
  1037. X*
  1038. X* Author:    Daniel Barrett
  1039. X* Version:    See the file "version.h".
  1040. X* Copyright:    None!  This program is in the Public Domain.
  1041. X*        Please share it with others.
  1042. X***************************************************************************/
  1043. X
  1044. X    
  1045. X#include "mp.h"
  1046. X#include "midi.h"
  1047. X
  1048. X
  1049. X/* Read data from MIDI.  Return the value of the next MIDI byte.  Because
  1050. X * reading byte-by-byte from the MIDI port is inefficient, we read as
  1051. X * much as we can and keep it in a static buffer. */
  1052. X    
  1053. XMIDI_RESULT FromMidi(FILE *in, MIDI_VALUE *value)
  1054. X{
  1055. X    static long bytesWaiting = 0L;    /* # bytes waiting at serial port. */
  1056. X    static UBYTE buf[BUFSIZ];    /* Static buffer. */
  1057. X    static long currentByte = 0L;    /* Index of next byte to return. */
  1058. X
  1059. X    if (currentByte >= bytesWaiting)
  1060. X    {
  1061. X        bytesWaiting = FastSerialRead(buf);
  1062. X        currentByte = 0L;
  1063. X    }
  1064. X
  1065. X    if (bytesWaiting == CTRL_C_NO_BYTES)
  1066. X    {
  1067. X        bytesWaiting = currentByte = 0L;
  1068. X        return(RESULT_STOP);
  1069. X    }
  1070. X    else if (bytesWaiting <= 0)
  1071. X    {
  1072. X        bytesWaiting = currentByte = 0L;
  1073. X        return(RESULT_ERROR);
  1074. X    }
  1075. X    else
  1076. X    {
  1077. X        *value = buf[currentByte++];
  1078. X        return(RESULT_OK);
  1079. X    }
  1080. X}
  1081. X
  1082. X
  1083. X/* Write a byte to MIDI.  It is inefficient to write 1 byte at a time, but
  1084. X * we want instant transmission.  I will rewrite this eventually. */
  1085. X    
  1086. XBOOL ToMidi(FILE *dummy, MIDI_VALUE value)
  1087. X{
  1088. X    PrepareToWriteMidi(&value, 1);
  1089. X    return(DoTheIO() == 1L);
  1090. X}
  1091. X
  1092. X/* Read 1 byte from text.  We use a finite state automaton.
  1093. X * If an error occurs, assign the value of the last character read
  1094. X * to *answer. */
  1095. X    
  1096. XMIDI_RESULT FromText(FILE *in, MIDI_VALUE *value)
  1097. X{
  1098. X    STATE_T state = STATE_NORMAL;
  1099. X    int c;
  1100. X    
  1101. X    *value = 0L;
  1102. X
  1103. X    while ((state != STATE_SUCCESS) && (state != STATE_ERROR)
  1104. X    &&     (state != STATE_OVERFLOW)
  1105. X    &&     ((c = getc(in)) != EOF))
  1106. X
  1107. X        state = NewState(c, state, value);
  1108. X
  1109. X    if (state == STATE_SUCCESS)
  1110. X        return(RESULT_OK);
  1111. X    else if (c == EOF && state == STATE_NORMAL)
  1112. X        return(RESULT_STOP);
  1113. X    else if (c == EOF)
  1114. X        return(RESULT_ERROR);
  1115. X    else if (state == STATE_OVERFLOW)
  1116. X        return(RESULT_OVERFLOW);
  1117. X    else
  1118. X    {
  1119. X        *value = c;
  1120. X        return(RESULT_ERROR);
  1121. X    }
  1122. X}
  1123. X
  1124. X
  1125. X/* Write 1 MIDI value as text. */
  1126. X    
  1127. XBOOL ToText(FILE *out, MIDI_VALUE value)
  1128. X{
  1129. X    static long byt = 0L;
  1130. X
  1131. X    fprintf(out, "<%6ld>   ", ++byt);
  1132. X    PrintNumber(value, out);
  1133. X}
  1134. X
  1135. X
  1136. X/* Read 1 MIDI value from a binary file.  Inefficient. */
  1137. X    
  1138. XMIDI_RESULT FromBinary(FILE *in, MIDI_VALUE *value)
  1139. X{
  1140. X    int c;
  1141. X    if ((c = getc(in)) != EOF)
  1142. X    {
  1143. X            *value = (MIDI_VALUE)c;
  1144. X        return(RESULT_OK);
  1145. X    }
  1146. X
  1147. X    return(RESULT_STOP);
  1148. X}
  1149. X
  1150. X
  1151. X/* Write 1 MIDI value to a binary file.  Inefficient. */
  1152. X    
  1153. XBOOL ToBinary(FILE *out, MIDI_VALUE value)
  1154. X{
  1155. X    return(putc(value, out) != EOF);
  1156. X}
  1157. X
  1158. X    
  1159. X/****************************************************************************
  1160. X* Skipping input.
  1161. X****************************************************************************/
  1162. X
  1163. X    
  1164. X/* Skip to the next valid text input. */
  1165. X
  1166. Xvoid SkipText(FILE *in, MIDI_VALUE value)
  1167. X{
  1168. X    register int c;
  1169. X
  1170. X    if (isspace(value))
  1171. X        return;
  1172. X
  1173. X    while ((c = getc(in)) != EOF && !isspace(c))
  1174. X        ;
  1175. X    if (c != EOF)
  1176. X        ungetc(c, in);
  1177. X}
  1178. X
  1179. X
  1180. X/* Skip to the next valid MIDI input by clearing the serial port buffer. */
  1181. X    
  1182. Xvoid SkipMidi(FILE *dummy, MIDI_VALUE junk)
  1183. X{
  1184. X    ResetSerialPort();
  1185. X}
  1186. X
  1187. X
  1188. X/* Skip to the next valid binary value.  This is currently just a stub. */
  1189. X    
  1190. Xvoid SkipBinary(FILE *in, MIDI_VALUE junk)
  1191. X{
  1192. X    return;
  1193. X}
  1194. END_OF_FILE
  1195. if test 3430 -ne `wc -c <'Source/iofunctions.c'`; then
  1196.     echo shar: \"'Source/iofunctions.c'\" unpacked with wrong size!
  1197. fi
  1198. # end of 'Source/iofunctions.c'
  1199. fi
  1200. if test -f 'Source/main.c' -a "${1}" != "-c" ; then 
  1201.   echo shar: Will not clobber existing file \"'Source/main.c'\"
  1202. else
  1203. echo shar: Extracting \"'Source/main.c'\" \(4433 characters\)
  1204. sed "s/^X//" >'Source/main.c' <<'END_OF_FILE'
  1205. X/**************************************************************************
  1206. X* main.c:    The main program and supporting stuff.
  1207. X*        Part of MP, the MIDI Playground.
  1208. X*
  1209. X* Author:    Daniel Barrett
  1210. X* Version:    See the file "version.h".
  1211. X* Copyright:    None!  This program is in the Public Domain.
  1212. X*        Please share it with others.
  1213. X***************************************************************************/
  1214. X
  1215. X    
  1216. X#include "mp.h"
  1217. X
  1218. XBOOL WorkbenchProgram(char *argv[]);
  1219. XBOOL CommandLineProgram(int argc, char *argv[]);
  1220. X    
  1221. Xmain(int argc, char *argv[])
  1222. X{
  1223. X    BOOL success;
  1224. X
  1225. X    if (argc == 0)
  1226. X        success = WorkbenchProgram(argv);
  1227. X    else
  1228. X        success = CommandLineProgram(argc, argv);
  1229. X
  1230. X    exit(success ? RETURN_OK : RETURN_FAIL);
  1231. X}
  1232. X
  1233. X    
  1234. X/************************************************************************
  1235. X* Initialization of important variables.
  1236. X************************************************************************/
  1237. X
  1238. Xvoid InitStuff(FLAGS theFlags[], FILE **in, FILE **out, char **inFile,
  1239. X        char **outFile)
  1240. X{
  1241. X    int i;
  1242. X
  1243. X    for (i=0; i<NUM_FLAGS; i++)    /* Flags. */
  1244. X        theFlags[i] = (FLAGS)0;
  1245. X
  1246. X    *in      = stdin;        /* Input file. */
  1247. X    *out     = stdout;        /* Output file. */
  1248. X    *inFile  = NULL;        /* Input file name. */
  1249. X    *outFile = NULL;        /* Output file name. */
  1250. X}
  1251. X
  1252. X    
  1253. X/************************************************************************
  1254. X* Open the serial port if necessary, and have fun!
  1255. X************************************************************************/
  1256. X
  1257. XBOOL MIDIPlayground(FLAGS theFlags[], FILE *in, FILE *out)
  1258. X{
  1259. X    if ((theFlags[FLAG_ITYPE] == OPT_MIDI)
  1260. X    ||  (theFlags[FLAG_OTYPE] == OPT_MIDI))
  1261. X    {
  1262. X        if (!SerialSetup(theFlags[FLAG_SYSEX]))
  1263. X            return(FALSE);
  1264. X        ResetSerialPort();
  1265. X    }
  1266. X
  1267. X    ReadAndWriteStuff(theFlags, in, out);
  1268. X
  1269. X
  1270. X    if ((theFlags[FLAG_ITYPE] == OPT_MIDI)
  1271. X    ||  (theFlags[FLAG_OTYPE] == OPT_MIDI))
  1272. X        SerialShutdown();
  1273. X
  1274. X    return(TRUE);        /* Stub. */
  1275. X}
  1276. X
  1277. X    
  1278. X/************************************************************************
  1279. X* Use the appropriate I/O functions until we're done.
  1280. X************************************************************************/
  1281. X
  1282. Xvoid ReadAndWriteStuff(FLAGS theFlags[], FILE *in, FILE *out)
  1283. X{
  1284. X    MIDI_RESULT    result;
  1285. X    MIDI_VALUE    value;
  1286. X    MIDI_RESULT    (*getfcn)(FILE *f, MIDI_VALUE *value);
  1287. X    BOOL        (*putfcn)(FILE *f, MIDI_VALUE value);
  1288. X    void        (*skipfcn)(FILE *f, MIDI_VALUE value);
  1289. X
  1290. X    SetTheFunctions(&getfcn, &putfcn, &skipfcn, theFlags);
  1291. X    
  1292. X    while ((result = getfcn(in, &value)) != RESULT_STOP)
  1293. X    {
  1294. X        switch (result)
  1295. X        {
  1296. X            case RESULT_OK:
  1297. X                putfcn(out, value);
  1298. X                break;
  1299. X            case RESULT_ERROR:
  1300. X                fprintf(out, "ERROR\n");
  1301. X                skipfcn(in, value);
  1302. X                break;
  1303. X            case RESULT_OVERFLOW:
  1304. X                fprintf(out, "VALUE TOO BIG (overflow)\n");
  1305. X                skipfcn(in, value);
  1306. X                break;
  1307. X            default:
  1308. X                skipfcn(in, value);
  1309. X                fprintf(out, "An unknown error occurred.\n");
  1310. X                break;
  1311. X        }
  1312. X    }
  1313. X}
  1314. X
  1315. X
  1316. X/************************************************************************
  1317. X* Choose the appropriate I/O functions.
  1318. X************************************************************************/
  1319. X
  1320. Xvoid SetTheFunctions(MIDI_RESULT (**getfcn)(), BOOL (**putfcn)(),
  1321. X            void (**skipfcn)(), FLAGS theFlags[])
  1322. X{
  1323. X    switch (theFlags[FLAG_ITYPE])
  1324. X    {
  1325. X        case OPT_TEXT:
  1326. X            *getfcn = FromText;
  1327. X            *skipfcn = SkipText;
  1328. X            break;
  1329. X        case OPT_BINARY:
  1330. X            *getfcn = FromBinary;
  1331. X            *skipfcn = SkipBinary;
  1332. X            break;
  1333. X        case OPT_MIDI:
  1334. X            *getfcn = FromMidi;
  1335. X            *skipfcn = SkipMidi;
  1336. X            break;
  1337. X        default:
  1338. X            *getfcn = FromText;    /* Least dangerous fcn. */
  1339. X            *skipfcn = SkipText;    /* Least dangerous fcn. */
  1340. X    }
  1341. X
  1342. X    switch (theFlags[FLAG_OTYPE])
  1343. X    {
  1344. X        case OPT_TEXT:
  1345. X            *putfcn = ToText;
  1346. X            break;
  1347. X        case OPT_BINARY:
  1348. X            *putfcn = ToBinary;
  1349. X            break;
  1350. X        case OPT_MIDI:
  1351. X            *putfcn = ToMidi;
  1352. X            break;
  1353. X        default:
  1354. X            *putfcn = ToText;    /* Least dangerous fcn. */
  1355. X            break;
  1356. X    }
  1357. X}
  1358. X
  1359. X
  1360. X/* Is "opt" a valid input/output type?  Set the flag too. */
  1361. X    
  1362. XBOOL CheckIOType(char opt, int ioFlag, FLAGS theFlags[])
  1363. X{
  1364. X    return(IsIOType(theFlags[ioFlag] = opt));
  1365. X}
  1366. X
  1367. X
  1368. X/* Is "ioType" a valid input/output type? */
  1369. X    
  1370. XBOOL IsIOType(char ioType)
  1371. X{
  1372. X    return(    (ioType == OPT_TEXT)
  1373. X    ||    (ioType == OPT_BINARY)
  1374. X    ||    (ioType == OPT_MIDI));
  1375. X}
  1376. X
  1377. X
  1378. X/* Did user specify both input and output types? */
  1379. X    
  1380. XBOOL CheckFlags(FLAGS theFlags[])
  1381. X{
  1382. X    return(theFlags[FLAG_ITYPE] && theFlags[FLAG_OTYPE]);
  1383. X}
  1384. X
  1385. X    
  1386. X/************************************************************************
  1387. X* ^C handling -- Manx stuff.
  1388. X************************************************************************/
  1389. X
  1390. Xvoid _abort(void)
  1391. X{
  1392. X    SerialShutdown();
  1393. X    exit(RETURN_FAIL);
  1394. X}
  1395. END_OF_FILE
  1396. if test 4433 -ne `wc -c <'Source/main.c'`; then
  1397.     echo shar: \"'Source/main.c'\" unpacked with wrong size!
  1398. fi
  1399. # end of 'Source/main.c'
  1400. fi
  1401. if test -f 'Source/midi.h' -a "${1}" != "-c" ; then 
  1402.   echo shar: Will not clobber existing file \"'Source/midi.h'\"
  1403. else
  1404. echo shar: Extracting \"'Source/midi.h'\" \(1182 characters\)
  1405. sed "s/^X//" >'Source/midi.h' <<'END_OF_FILE'
  1406. X#ifndef _MIDI_H
  1407. X#define _MIDI_H    1
  1408. X
  1409. X/***************************************************************************
  1410. X * MIDI values that are independent of any particular synthesizer.
  1411. X ***************************************************************************/
  1412. X
  1413. X/***************************************************************************
  1414. X * Some system-exclusive message constants.
  1415. X ***************************************************************************/
  1416. X
  1417. X#define    SYSEX_BEGIN    0xF0
  1418. X#define    SYSEX_END    0xF7
  1419. X
  1420. X/***************************************************************************
  1421. X * Allow use of MIDI interfaces not attached to the internal serial port,
  1422. X * unit 0.  Here are the defaults.
  1423. X ***************************************************************************/
  1424. X
  1425. X#define    DEFAULT_MIDI_DEVICE    "serial.device"
  1426. X#define    DEFAULT_MIDI_UNIT    0
  1427. X#define    MIDI_ENV_VAR        "MP_MIDI_DEVICE"
  1428. X
  1429. X#define    MIDI_BAUD_RATE        31250
  1430. X
  1431. X#ifndef CTRL_C_NO_BYTES
  1432. X#define CTRL_C_NO_BYTES        (-1)
  1433. X#endif
  1434. X
  1435. X/***************************************************************************
  1436. X * End of this header file.
  1437. X ***************************************************************************/
  1438. X
  1439. X#endif /* _MIDI_H */
  1440. END_OF_FILE
  1441. if test 1182 -ne `wc -c <'Source/midi.h'`; then
  1442.     echo shar: \"'Source/midi.h'\" unpacked with wrong size!
  1443. fi
  1444. # end of 'Source/midi.h'
  1445. fi
  1446. if test -f 'Source/mp.h' -a "${1}" != "-c" ; then 
  1447.   echo shar: Will not clobber existing file \"'Source/mp.h'\"
  1448. else
  1449. echo shar: Extracting \"'Source/mp.h'\" \(8727 characters\)
  1450. sed "s/^X//" >'Source/mp.h' <<'END_OF_FILE'
  1451. X/**************************************************************************
  1452. X* mp.h:        Main header file.
  1453. X*        Part of MP, the MIDI Playground.
  1454. X*
  1455. X* Author:    Daniel Barrett
  1456. X* Version:    See the file "version.h".
  1457. X* Copyright:    None!  This program is in the Public Domain.
  1458. X*        Please share it with others.
  1459. X***************************************************************************/
  1460. X
  1461. X    
  1462. X#ifndef _MP_H
  1463. X
  1464. X#include <devices/serial.h>
  1465. X#include <exec/devices.h>
  1466. X#include <exec/memory.h>
  1467. X#include <exec/ports.h>
  1468. X#include <exec/types.h>
  1469. X#include <exec/interrupts.h>
  1470. X#include <libraries/dos.h>
  1471. X#include <libraries/dosextens.h>
  1472. X#include <workbench/startup.h>
  1473. X#include <workbench/workbench.h>
  1474. X#include <functions.h>
  1475. X#include <stdio.h>
  1476. X
  1477. X#ifndef __C_MACROS__
  1478. X#define __C_MACROS__
  1479. X#endif
  1480. X#include <ctype.h>
  1481. X
  1482. X
  1483. X/**************************************************************************
  1484. X* Types.
  1485. X**************************************************************************/
  1486. X    
  1487. Xtypedef unsigned char    STATE_T;    /* An automaton state.        */
  1488. Xtypedef UBYTE        MIDI_VALUE;    /* A single MIDI data value.    */
  1489. Xtypedef    signed char    MIDI_RESULT;    /* What happened while reading?    */
  1490. Xtypedef char        FLAGS;        /* Internal flags.        */
  1491. X    
  1492. X/**************************************************************************
  1493. X* Return values from our input routine.
  1494. X**************************************************************************/
  1495. X    
  1496. X#define    RESULT_OK        (MIDI_RESULT)(1)    /* Legal value read.   */
  1497. X#define    RESULT_ERROR        (MIDI_RESULT)(2)    /* Illegal value read. */
  1498. X#define    RESULT_OVERFLOW        (MIDI_RESULT)(3)    /* Value overflowed.   */
  1499. X#define    RESULT_STOP        (MIDI_RESULT)(4)    /* End of data.        */
  1500. X    
  1501. X/**************************************************************************
  1502. X* States of our finite automaton for reading input.
  1503. X**************************************************************************/
  1504. X    
  1505. X#define    STATE_SUCCESS        1    /* Got a legal value. */
  1506. X#define    STATE_ERROR        2    /* Had an input error. */
  1507. X#define    STATE_OVERFLOW        3    /* Read too big a value. */
  1508. X#define    STATE_NORMAL        4    /* Haven't read anything yet. */
  1509. X#define    STATE_INCOMMENT        5    /* Skipping a comment. */
  1510. X#define    STATE_INDECIMAL        6    /* Reading a base 10 number. */
  1511. X#define    STATE_LEADZERO        7    /* Read a leading zero. */
  1512. X#define    STATE_INOCTAL        8    /* Reading an octal number. */
  1513. X#define    STATE_STARTHEX        9    /* Read 1st digit of hex number. */
  1514. X#define    STATE_INHEX        10    /* Reading a hex number. */
  1515. X#define    STATE_STARTBINARY    11    /* Read 1st symbol of binary num. */
  1516. X#define    STATE_INBINARY        12    /* Reading a binary number. */
  1517. X#define    STATE_NEGATIVE        13    /* UNUSED.  FOR FUTURE UPDATE. */
  1518. X#define    STATE_INCHAR        14    /* Reading a char constant. */
  1519. X#define    STATE_EXPECTQUOTE    15    /* Finishing a char constant. */
  1520. X#define    STATE_BACKSLASHINCHAR    16    /* Backslash in a char constant. */
  1521. X#define    STATE_BACKSLASHINSTRING    17    /* Backslash in a string constant. */
  1522. X#define    STATE_INCLUDEFILE    18    /* UNUSED.  FOR FUTURE UPDATE. */
  1523. X
  1524. X    
  1525. X/**************************************************************************
  1526. X* Macros for converting characters to numbers:
  1527. X*
  1528. X*    D_TO_INT(c)    Convert a digit to its numeric value.
  1529. X*    L_TO_INT(c)    Convert a letter (A..F) to its base 16 value.
  1530. X*    H_TO_INT(c)    Convert a hex digit to its numeric value.
  1531. X**************************************************************************/
  1532. X    
  1533. X#define    D_TO_INT(c)    ((long)((c) - '0'))
  1534. X#define    L_TO_INT(c)    ((long)((toupper(c)) - 'A') + 10)
  1535. X#define    H_TO_INT(c)    (isdigit(c) ? D_TO_INT(c) : L_TO_INT(c))
  1536. X    
  1537. X/**************************************************************************
  1538. X* Macros for classifying types of input.  The rest are in <ctype.h>.
  1539. X**************************************************************************/
  1540. X    
  1541. X#define    isoctal(c)    (((c) >= '0') && ((c) <= '7'))
  1542. X
  1543. X/**************************************************************************
  1544. X* Other macros.
  1545. X**************************************************************************/
  1546. X
  1547. X#define    MAX(a,b)    (((a) > (b)) ? (a) : (b))
  1548. X#define    MIN(a,b)    (((a) < (b)) ? (a) : (b))
  1549. X
  1550. X#define OpenReadFile(filename)    OpenAFile(filename, "r", "read")
  1551. X#define OpenWriteFile(filename)    OpenAFile(filename, "w", "write")
  1552. X
  1553. X    
  1554. X/**************************************************************************
  1555. X* The largest legal value our input routine can handle.
  1556. X**************************************************************************/
  1557. X    
  1558. X#define    LARGEST_VALUE        (MIDI_VALUE)(255)
  1559. X#define    BITS_IN_MIDI_VALUE    BITSPERBYTE        /* in types.h */
  1560. X
  1561. X/***************************************************************************
  1562. X* Character constants for classifying the input.
  1563. X***************************************************************************/
  1564. X
  1565. X#define    START_BINARY    '#'    /* Symbol for start of binary number. */
  1566. X#define    HELP_SYMBOL    '?'    /* Symbol for help request from user. */
  1567. X#define    START_COMMENT    ';'    /* Start-comment symbol. */
  1568. X    
  1569. X/***************************************************************************
  1570. X* Command-line Options.
  1571. X***************************************************************************/
  1572. X
  1573. X#define    OPT_INPUT    'i'        /* Input format. */
  1574. X#define    OPT_OUTPUT    'o'        /* Output format. */
  1575. X#define    OPT_TEXT    't'        /* Text I/O. */
  1576. X#define    OPT_BINARY    'b'        /* Binary I/O. */
  1577. X#define    OPT_MIDI    'm'        /* MIDI I/O. */
  1578. X#define    OPT_SYSEX    'x'        /* UNUSED. FOR FUTURE UPDATE. */
  1579. X#define    OPT_INFILE    'g'        /* Get from file. */
  1580. X#define    OPT_OUTFILE    'p'        /* Put to file. */
  1581. X
  1582. X/* For getopt(). */
  1583. X#define    GETOPT_OPTIONS    "i:o:g:p:x";
  1584. Xextern int optind;
  1585. Xextern char *optarg;
  1586. X
  1587. X/***************************************************************************
  1588. X* Flags, and their associated macros.
  1589. X***************************************************************************/
  1590. X
  1591. X#define    NUM_FLAGS    3    /* How many flags? */
  1592. X
  1593. X#define    FLAG_ITYPE    0    /* Flag ID's. */
  1594. X#define    FLAG_OTYPE    1
  1595. X#define    FLAG_SYSEX    2
  1596. X
  1597. X    
  1598. X/***************************************************************************
  1599. X* Prototypes.
  1600. X***************************************************************************/
  1601. X
  1602. X/* read.c */
  1603. XSTATE_T NewState(int c, STATE_T state, MIDI_VALUE *answer);
  1604. XSTATE_T NonStringState(int c, STATE_T state, MIDI_VALUE *answer);
  1605. XSTATE_T DoNormal(int c, MIDI_VALUE *answer);
  1606. XSTATE_T DoDecimal(int c, MIDI_VALUE *answer);
  1607. XSTATE_T DoOctal(int c, MIDI_VALUE *answer);
  1608. XSTATE_T DoHex(int c, MIDI_VALUE *answer);
  1609. XSTATE_T DoInHex(int c, MIDI_VALUE *answer);
  1610. XSTATE_T DoBinary(int c, MIDI_VALUE *answer);
  1611. XSTATE_T DoInBinary(int c, MIDI_VALUE *answer);
  1612. XSTATE_T DoLeadZero(int c, MIDI_VALUE *answer);
  1613. XSTATE_T IncreaseIfPossible(MIDI_VALUE *answer, int newNum, int base, 
  1614. X                STATE_T newState);
  1615. XSTATE_T DoInChar(int c, MIDI_VALUE *answer);
  1616. XSTATE_T DoExpectQuote(int c, MIDI_VALUE *answer);
  1617. XSTATE_T DoBackslash(int c, MIDI_VALUE *answer, STATE_T newState);
  1618. XSTATE_T DoInString(int c, STATE_T state, MIDI_VALUE *answer,
  1619. X             short *inString);
  1620. XSTATE_T DoComment(int c);
  1621. Xvoid InputHelp();
  1622. X
  1623. Xvoid PrintNumber(MIDI_VALUE number, FILE *out);
  1624. Xvoid PrintBinary(MIDI_VALUE number, FILE *out);
  1625. X
  1626. X/* serial.c */
  1627. Xshort SerialSetup(FLAGS sysex);
  1628. Xvoid SerialShutdown(void);
  1629. Xvoid ResetSerialPort(void);
  1630. Xlong AnyMidiData(void);
  1631. Xvoid PrepareToReadMidi(UBYTE *buf, int len);
  1632. Xvoid PrepareToWriteMidi(UBYTE *buf, int len);
  1633. Xlong DoTheIO(void);
  1634. Xlong FastSerialRead(UBYTE buf[]);
  1635. X
  1636. X/* iofunctions.c */
  1637. XMIDI_RESULT FromMidi(FILE *in, MIDI_VALUE *value);
  1638. XBOOL ToMidi(FILE *in, MIDI_VALUE value);
  1639. XMIDI_RESULT FromText(FILE *in, MIDI_VALUE *value);
  1640. XBOOL ToText(FILE *in, MIDI_VALUE value);
  1641. XMIDI_RESULT FromBinary(FILE *in, MIDI_VALUE *value);
  1642. XBOOL ToBinary(FILE *in, MIDI_VALUE value);
  1643. Xvoid SkipText(FILE *in, MIDI_VALUE value);
  1644. Xvoid SkipMidi(FILE *in, MIDI_VALUE junk);
  1645. Xvoid SkipBinary(FILE *in, MIDI_VALUE junk);
  1646. X
  1647. X/* main.c */
  1648. XBOOL IsIOType(char ioType);
  1649. XBOOL CheckIOType(char opt, int ioFlag, FLAGS theFlags[]);
  1650. XBOOL HandleOptions(int argc, char *argv[], FLAGS theFlags[],
  1651. X           char **infile, char **outfile);
  1652. Xvoid ReadAndWriteStuff(FLAGS theFlags[], FILE *in, FILE *out);
  1653. Xvoid SetTheFunctions(MIDI_RESULT (**getfcn)(), BOOL (**putfcn)(),
  1654. X            void (**skipfcn)(), FLAGS theFlags[]);
  1655. XBOOL CheckFlags(FLAGS theFlags[]);
  1656. Xvoid InitStuff(FLAGS theFlags[], FILE **in, FILE **out, char **inFile,
  1657. X        char **outFile);
  1658. XBOOL MIDIPlayground(FLAGS theFlags[], FILE *in, FILE *out);
  1659. X
  1660. X/* wb.c */
  1661. X
  1662. X/* help.c */
  1663. Xvoid BegForUsage(char *progName);
  1664. Xvoid Help(char *progName);
  1665. X
  1666. X/* files.c */
  1667. XFILE *OpenAFile(char *filename, char *mode, char *readOrWrite);
  1668. XBOOL FileExists(char *filename);
  1669. XBOOL DontOverwriteExistingFile(char *filename);
  1670. XBOOL SetupFiles(char *infile, char *outfile, FILE **in, FILE **out);
  1671. Xvoid CloseFiles(FILE *in, FILE *out, char *filein, char *fileout);
  1672. XBOOL MakeFilename(char **dest, char *src);
  1673. X
  1674. X#ifndef OpenReadFile
  1675. XFILE *OpenReadFile(char *filename);
  1676. X#endif
  1677. X
  1678. X#ifndef OpenWriteFile
  1679. XFILE *OpenWriteFile(char *filename);
  1680. X#endif
  1681. X
  1682. X
  1683. X#endif /* _MP_H */
  1684. END_OF_FILE
  1685. if test 8727 -ne `wc -c <'Source/mp.h'`; then
  1686.     echo shar: \"'Source/mp.h'\" unpacked with wrong size!
  1687. fi
  1688. # end of 'Source/mp.h'
  1689. fi
  1690. if test -f 'Source/serial.c' -a "${1}" != "-c" ; then 
  1691.   echo shar: Will not clobber existing file \"'Source/serial.c'\"
  1692. else
  1693. echo shar: Extracting \"'Source/serial.c'\" \(7123 characters\)
  1694. sed "s/^X//" >'Source/serial.c' <<'END_OF_FILE'
  1695. X/**************************************************************************
  1696. X* serial.c:    Serial port access functions.
  1697. X*        Part of MP, the MIDI Playground.
  1698. X*
  1699. X* Author:    Daniel Barrett
  1700. X* Version:    See the file "version.h".
  1701. X* Copyright:    None!  This program is in the Public Domain.
  1702. X*        Please share it with others.
  1703. X***************************************************************************/
  1704. X
  1705. X    
  1706. X#include "mp.h"
  1707. X#include "midi.h"
  1708. X
  1709. Xstatic struct MsgPort    *MidiPort    = NULL;
  1710. Xstatic struct IOExtSer    *Midi        = NULL;
  1711. Xlong serialFlags            = 0L;
  1712. X
  1713. X#define    F_MIDIPORT    1
  1714. X#define    F_MIDI        2
  1715. X#define    F_DEVICE    4
  1716. X#define    F_SERPARAMS    8
  1717. X
  1718. X
  1719. XBOOL AllDigits(char *str);
  1720. Xchar *GetEnv(char *str);
  1721. XBOOL MakeSerialDeviceName(char *str, char *device, int *unit);
  1722. X
  1723. X    
  1724. X/****************************************************************************
  1725. X * SerialSetup:  Open the serial port and its message port.
  1726. X * Allow for an alternate MIDI device in an environment variable.
  1727. X ***************************************************************************/
  1728. X
  1729. XBOOL SerialSetup(FLAGS sysex)
  1730. X{
  1731. X    char deviceName[BUFSIZ], *envVar;
  1732. X    int unit;
  1733. X
  1734. X    /* Set the defaults. */
  1735. X
  1736. X    strcpy(deviceName, DEFAULT_MIDI_DEVICE);
  1737. X    unit = DEFAULT_MIDI_UNIT;
  1738. X
  1739. X    /* If environment variable is set, find the real MIDI device info. */
  1740. X
  1741. X    if ((envVar = GetEnv(MIDI_ENV_VAR))
  1742. X    && (!MakeSerialDeviceName(envVar, deviceName, &unit)))
  1743. X        return(FALSE);
  1744. X
  1745. X    /* Create a port. */
  1746. X
  1747. X    if (! (MidiPort = CreatePort(0, 0)) )
  1748. X    {
  1749. X        fprintf(stderr, "Cannot create port\n");
  1750. X        SerialShutdown();
  1751. X        return(FALSE);
  1752. X    }
  1753. X    else
  1754. X        serialFlags |= F_MIDIPORT;
  1755. X
  1756. X    /* Create an extended I/O structure. */
  1757. X
  1758. X    if (! (Midi = (struct IOExtSer *)
  1759. X    CreateExtIO(MidiPort, sizeof(struct IOExtSer))))
  1760. X    {
  1761. X        fprintf(stderr, "Cannot create extended I/O structure\n");
  1762. X        SerialShutdown();
  1763. X        return(FALSE);
  1764. X    }
  1765. X    else
  1766. X        serialFlags |= F_MIDI;
  1767. X
  1768. X    /* Open the serial device. */
  1769. X
  1770. X    Midi->io_SerFlags = SERF_SHARED;
  1771. X    if (OpenDevice(deviceName, unit, (struct IORequest *)Midi, 0))
  1772. X    {
  1773. X        fprintf(stderr,
  1774. X            "Cannot open serial device \"%s\", unit %d.\n",
  1775. X            deviceName, unit);
  1776. X        SerialShutdown();
  1777. X        return(FALSE);
  1778. X    }
  1779. X    else
  1780. X        serialFlags |= F_DEVICE;
  1781. X
  1782. X    /* Set the serial device parameters. */
  1783. X
  1784. X    Midi->io_SerFlags        = SERF_RAD_BOOGIE;
  1785. X    if (sysex)
  1786. X    {
  1787. X        Midi->io_TermArray.TermArray0    = 0xF7F7F7F7;
  1788. X        Midi->io_TermArray.TermArray1    = 0xF7F7F7F7;
  1789. X        Midi->io_SerFlags |= SERF_EOFMODE;
  1790. X    }
  1791. X    Midi->io_Baud            = MIDI_BAUD_RATE;
  1792. X    Midi->io_ExtFlags        = 0;    /* For future compatibility */
  1793. X    Midi->IOSer.io_Command        = SDCMD_SETPARAMS;
  1794. X
  1795. X    if (DoIO((struct IORequest *)Midi) != 0)
  1796. X     {
  1797. X        fprintf(stderr, "Cannot set serial parameters.\n");
  1798. X        SerialShutdown();
  1799. X        return(FALSE);
  1800. X    }
  1801. X    else
  1802. X        serialFlags |= F_SERPARAMS;
  1803. X
  1804. X    return(TRUE);
  1805. X}
  1806. X
  1807. X
  1808. X/****************************************************************************
  1809. X * SerialShutdown:  Close the serial port and its message port.
  1810. X ***************************************************************************/
  1811. X
  1812. Xvoid SerialShutdown(void)
  1813. X{
  1814. X    if (serialFlags & F_DEVICE)
  1815. X    {
  1816. X        ResetSerialPort();
  1817. X        AbortIO((struct IORequest *)Midi);
  1818. X        WaitIO((struct IORequest *)Midi);
  1819. X        CloseDevice((struct IORequest *)Midi);
  1820. X    }
  1821. X
  1822. X    if (serialFlags & F_MIDI)
  1823. X        DeleteExtIO((struct IORequest *)Midi);
  1824. X
  1825. X    if (serialFlags & F_MIDIPORT)
  1826. X        DeletePort(MidiPort);
  1827. X}
  1828. X
  1829. X/****************************************************************************
  1830. X * ResetSerialPort:  Clear all data from the serial port.
  1831. X ***************************************************************************/
  1832. X
  1833. Xvoid ResetSerialPort(void)
  1834. X{
  1835. X    Midi->IOSer.io_Command = CMD_CLEAR;
  1836. X    DoIO((struct IORequest *)Midi);
  1837. X}
  1838. X
  1839. X
  1840. X/****************************************************************************
  1841. X * Is any data there?
  1842. X ***************************************************************************/
  1843. X
  1844. Xlong AnyMidiData(void)
  1845. X{
  1846. X    Midi->IOSer.io_Command = SDCMD_QUERY;
  1847. X    DoIO((struct IORequest *)Midi);
  1848. X    return(Midi->IOSer.io_Actual);
  1849. X}
  1850. X
  1851. X    
  1852. X/****************************************************************************
  1853. X * PrepareToReadMidi:    Prepare a READ request for the MIDI port.
  1854. X * PrepareToWriteMidi:    Prepare a WRITE request for the MIDI port.
  1855. X ***************************************************************************/
  1856. X
  1857. Xvoid PrepareToReadMidi(UBYTE buf[], int len)
  1858. X{
  1859. X    Midi->IOSer.io_Command = CMD_READ;
  1860. X    Midi->IOSer.io_Data = (APTR)buf;
  1861. X    Midi->IOSer.io_Length = len;
  1862. X}
  1863. X
  1864. X
  1865. Xvoid PrepareToWriteMidi(UBYTE buf[], int len)
  1866. X{
  1867. X    Midi->IOSer.io_Command = CMD_WRITE;
  1868. X    Midi->IOSer.io_Data = (APTR)buf;
  1869. X    Midi->IOSer.io_Length = len;
  1870. X}
  1871. X
  1872. X
  1873. X/****************************************************************************
  1874. X* DoTheIO:  General-purpose MIDI I/O routine.  Quits on ^C.
  1875. X****************************************************************************/
  1876. X
  1877. Xlong DoTheIO(void)
  1878. X{
  1879. X    int mask, temp;
  1880. X    long bytesDone = 0L;
  1881. X
  1882. X    mask = SIGBREAKF_CTRL_C | (1L << MidiPort->mp_SigBit);
  1883. X    SendIO((struct IORequest *)Midi);
  1884. X
  1885. X    while (1)
  1886. X    {
  1887. X        temp = Wait(mask);
  1888. X        if (temp & SIGBREAKF_CTRL_C)
  1889. X        {
  1890. X            bytesDone = CTRL_C_NO_BYTES;
  1891. X            break;
  1892. X        }
  1893. X
  1894. X        if (CheckIO((struct IORequest *)Midi))
  1895. X        {
  1896. X            WaitIO((struct IORequest *)Midi);
  1897. X            bytesDone = Midi->IOSer.io_Actual;
  1898. X            break;
  1899. X        }
  1900. X    }
  1901. X
  1902. X    AbortIO((struct IORequest *)Midi);
  1903. X    WaitIO((struct IORequest *)Midi);
  1904. X    return(bytesDone);
  1905. X}
  1906. X
  1907. X
  1908. X/****************************************************************************
  1909. X* Fast serial reading routine, from idea on 1.3 RKM's page 863.
  1910. X* If any data is waiting, get all of it with DoIO().  Otherwise, post an
  1911. X* asynchronous request for 1 byte.  Repeat this in the calling program.
  1912. X****************************************************************************/
  1913. X
  1914. Xlong FastSerialRead(UBYTE buf[])
  1915. X{
  1916. X    long bytesWaiting, bytesRead;
  1917. X
  1918. X    if ((bytesWaiting = AnyMidiData()) > 0)
  1919. X    {
  1920. X        PrepareToReadMidi(buf, MIN(bytesWaiting, BUFSIZ));
  1921. X        DoIO((struct IORequest *)Midi);
  1922. X        return(Midi->IOSer.io_Actual);
  1923. X    }
  1924. X    else
  1925. X    {
  1926. X        PrepareToReadMidi(buf, 1);
  1927. X        return(DoTheIO());
  1928. X    }
  1929. X}
  1930. X
  1931. X    
  1932. X/****************************************************************************
  1933. X* Allow the use of another MIDI device than serial.device.
  1934. X* Environment variable syntax is "DEVICENAME:UNITNUMBER".
  1935. X* For example:  "midi.device:2".
  1936. X*
  1937. X* "device" MUST be preallocated.
  1938. X****************************************************************************/
  1939. X
  1940. XBOOL MakeSerialDeviceName(char *str, char *device, int *unit)
  1941. X{
  1942. X    while (str && *str && (*str != ':'))
  1943. X        *(device++) = *(str++);
  1944. X
  1945. X    *device = '\0';
  1946. X
  1947. X    if ((*str != ':') || *(str+1) == '\0')
  1948. X    {
  1949. X        fprintf(stderr,
  1950. X            "Your MIDI device name (variable "
  1951. X            MIDI_ENV_VAR
  1952. X            ") is missing a colon\nand/or a unit number.\n");
  1953. X        return(FALSE);
  1954. X    }
  1955. X    str++;
  1956. X
  1957. X    if (!AllDigits(str))
  1958. X    {
  1959. X        fprintf(stderr,
  1960. X            "Your MIDI device unit number (variable "
  1961. X            MIDI_ENV_VAR
  1962. X            ") must be\na positive integer.\n");
  1963. X        return(FALSE);
  1964. X    }
  1965. X    else
  1966. X        *unit = atoi(str);
  1967. X
  1968. X    return(TRUE);
  1969. X}
  1970. X
  1971. X
  1972. X/* AllDigits:    Return TRUE iff the string "str" consists only of digits. */
  1973. X
  1974. XBOOL AllDigits(char *str)
  1975. X{
  1976. X    if ((!str) || (*str == '\0'))        /* NULL or empty string. */
  1977. X        return(FALSE);
  1978. X    else
  1979. X        while (*str)            /* For each character... */
  1980. X            if (!isdigit(*str))    /*  if not a digit...    */
  1981. X                return(FALSE);    /*  goodbye!             */
  1982. X            else
  1983. X                str++;
  1984. X    return(TRUE);                /* All were digits.      */
  1985. X}
  1986. END_OF_FILE
  1987. if test 7123 -ne `wc -c <'Source/serial.c'`; then
  1988.     echo shar: \"'Source/serial.c'\" unpacked with wrong size!
  1989. fi
  1990. # end of 'Source/serial.c'
  1991. fi
  1992. if test -f 'Source/text.c' -a "${1}" != "-c" ; then 
  1993.   echo shar: Will not clobber existing file \"'Source/text.c'\"
  1994. else
  1995. echo shar: Extracting \"'Source/text.c'\" \(9628 characters\)
  1996. sed "s/^X//" >'Source/text.c' <<'END_OF_FILE'
  1997. X/**************************************************************************
  1998. X* text.c:    Functions for text input/output.
  1999. X*        Part of MP, the MIDI Playground.
  2000. X*
  2001. X* Author:    Daniel Barrett
  2002. X* Version:    See the file "version.h".
  2003. X* Copyright:    None!  This program is in the Public Domain.
  2004. X*        Please share it with others.
  2005. X***************************************************************************/
  2006. X
  2007. X    
  2008. X#include "mp.h"
  2009. X
  2010. X
  2011. X/* Given the currently read character and the current state, compute
  2012. X * the new state and the MIDI value. */
  2013. X    
  2014. XSTATE_T NewState(int c, STATE_T state, MIDI_VALUE *answer)
  2015. X{
  2016. X    static BOOL inString = FALSE;
  2017. X
  2018. X    if (inString)
  2019. X        return(DoInString(c, state, answer, &inString));
  2020. X    else if (c == HELP_SYMBOL)
  2021. X    {
  2022. X        InputHelp();
  2023. X        return(state);
  2024. X    }
  2025. X    else if (state == STATE_NORMAL && c == '\"')
  2026. X    {
  2027. X        inString = TRUE;
  2028. X        return(STATE_NORMAL);    /* Doesn't matter. */
  2029. X    }
  2030. X    else
  2031. X        return(NonStringState(c, state, answer));
  2032. X}
  2033. X
  2034. X/****************************************************************************
  2035. X* Our finite automaton for non-strings.  Process the character and return
  2036. X* the new state.
  2037. X****************************************************************************/
  2038. X    
  2039. XSTATE_T NonStringState(int c, STATE_T state, MIDI_VALUE *answer)
  2040. X{
  2041. X    switch (state)
  2042. X    {
  2043. X        case STATE_NORMAL:    return(DoNormal(c, answer));
  2044. X        case STATE_INCOMMENT:    return(DoComment(c));
  2045. X        case STATE_INDECIMAL:    return(DoDecimal(c, answer));
  2046. X        case STATE_INOCTAL:    return(DoOctal(c, answer));
  2047. X        case STATE_STARTHEX:    return(DoHex(c, answer));
  2048. X        case STATE_INHEX:    return(DoInHex(c, answer));
  2049. X        case STATE_LEADZERO:    return(DoLeadZero(c, answer));
  2050. X        case STATE_INCHAR:    return(DoInChar(c, answer));
  2051. X        case STATE_STARTBINARY:    return(DoBinary(c, answer));
  2052. X        case STATE_INBINARY:    return(DoInBinary(c, answer));
  2053. X        case STATE_EXPECTQUOTE:    return(DoExpectQuote(c, answer));
  2054. X        case STATE_BACKSLASHINCHAR:
  2055. X            return(DoBackslash(c, answer, STATE_EXPECTQUOTE));
  2056. X        case STATE_SUCCESS:    
  2057. X        case STATE_OVERFLOW:    
  2058. X        case STATE_ERROR:    return(state);
  2059. X    }
  2060. X}
  2061. X
  2062. X
  2063. X/****************************************************************************
  2064. X* We are not currently in a number.  A character is read; decide what to
  2065. X* do with it.
  2066. X****************************************************************************/
  2067. X    
  2068. XSTATE_T DoNormal(int c, MIDI_VALUE *answer)
  2069. X{
  2070. X    if (isspace(c))
  2071. X        return(STATE_NORMAL);
  2072. X    else if (c == START_COMMENT)
  2073. X        return(STATE_INCOMMENT);
  2074. X    else if (c == START_BINARY)
  2075. X        return(STATE_STARTBINARY);
  2076. X    else if (c == '\'')
  2077. X        return(STATE_INCHAR);
  2078. X    else if (c == '0')
  2079. X        return(STATE_LEADZERO);
  2080. X    else if (toupper(c) == 'H')
  2081. X        return(STATE_STARTHEX);
  2082. X    else if (isdigit(c))
  2083. X    {
  2084. X        *answer = D_TO_INT(c);
  2085. X        return(STATE_INDECIMAL);
  2086. X    }
  2087. X    else if (isxdigit(c))
  2088. X    {
  2089. X        *answer = H_TO_INT(c);
  2090. X        return(STATE_INHEX);
  2091. X    }
  2092. X    else
  2093. X        return(STATE_ERROR);
  2094. X}
  2095. X
  2096. X    
  2097. X/****************************************************************************
  2098. X* Base 10 (decimal) numbers.
  2099. X****************************************************************************/
  2100. X    
  2101. XSTATE_T DoDecimal(int c, MIDI_VALUE *answer)
  2102. X{
  2103. X    if (isdigit(c))
  2104. X        return(IncreaseIfPossible(answer, D_TO_INT(c), 10, 
  2105. X            STATE_INDECIMAL));
  2106. X    else if (isspace(c))
  2107. X        return(STATE_SUCCESS);
  2108. X    else
  2109. X        return(STATE_ERROR);
  2110. X}
  2111. X
  2112. X    
  2113. X/****************************************************************************
  2114. X* Octal numbers.
  2115. X****************************************************************************/
  2116. X    
  2117. XSTATE_T DoOctal(int c, MIDI_VALUE *answer)
  2118. X{
  2119. X    if (isoctal(c))
  2120. X        return(IncreaseIfPossible(answer, D_TO_INT(c), 8, 
  2121. X            STATE_INOCTAL));
  2122. X    else if (isspace(c))
  2123. X        return(STATE_SUCCESS);
  2124. X    else
  2125. X        return(STATE_ERROR);
  2126. X}
  2127. X
  2128. X
  2129. X/****************************************************************************
  2130. X* Hexadecimal numbers.
  2131. X****************************************************************************/
  2132. X    
  2133. XSTATE_T DoHex(int c, MIDI_VALUE *answer)
  2134. X{
  2135. X    if (isxdigit(c))
  2136. X    {
  2137. X        *answer = H_TO_INT(c);
  2138. X        return(STATE_INHEX);
  2139. X    }
  2140. X    else
  2141. X        return(STATE_ERROR);
  2142. X}
  2143. X
  2144. X
  2145. XSTATE_T DoInHex(int c, MIDI_VALUE *answer)
  2146. X{
  2147. X    if (isxdigit(c))
  2148. X        return(IncreaseIfPossible(answer, H_TO_INT(c), 16, 
  2149. X            STATE_INHEX));
  2150. X    else if (isspace(c))
  2151. X        return(STATE_SUCCESS);
  2152. X    else
  2153. X        return(STATE_ERROR);
  2154. X}
  2155. X
  2156. X
  2157. X/****************************************************************************
  2158. X* Binary numbers.
  2159. X****************************************************************************/
  2160. X    
  2161. XSTATE_T DoBinary(int c, MIDI_VALUE *answer)
  2162. X{
  2163. X    if ((c == '0') || (c == '1'))
  2164. X    {
  2165. X            *answer = D_TO_INT(c);
  2166. X        return(STATE_INBINARY);
  2167. X    }
  2168. X    else
  2169. X        return(STATE_ERROR);
  2170. X}
  2171. X
  2172. X    
  2173. XSTATE_T DoInBinary(int c, MIDI_VALUE *answer)
  2174. X{
  2175. X    if ((c == '0') || (c == '1'))
  2176. X        return(IncreaseIfPossible(answer, D_TO_INT(c), 2, 
  2177. X            STATE_INBINARY));
  2178. X    else if (isspace(c))
  2179. X        return(STATE_SUCCESS);
  2180. X    else
  2181. X        return(STATE_ERROR);
  2182. X}
  2183. X
  2184. X    
  2185. X/****************************************************************************
  2186. X* Hook for negative numbers.  Commented out right now.
  2187. X****************************************************************************/
  2188. X    
  2189. X#ifdef ALLOW_NEGATIVE
  2190. XSTATE_T DoNegative(int c, MIDI_VALUE *answer)
  2191. X{
  2192. X    if (c == '0')
  2193. X        return(STATE_LEADZERO);
  2194. X    else if (isdigit(c))
  2195. X    {
  2196. X        return(STATE_INDECIMAL);
  2197. X    }
  2198. X    else
  2199. X        return(STATE_ERROR);
  2200. X}
  2201. X#endif /* ALLOW_NEGATIVE */
  2202. X
  2203. X    
  2204. X/****************************************************************************
  2205. X* Leading zero was found:  Do octal or hexadecimal as required.
  2206. X****************************************************************************/
  2207. X    
  2208. XSTATE_T DoLeadZero(int c, MIDI_VALUE *answer)
  2209. X{
  2210. X    if (toupper(c) == 'X')
  2211. X        return(STATE_STARTHEX);
  2212. X    else if (isoctal(c))
  2213. X    {
  2214. X        *answer = D_TO_INT(c);
  2215. X        return(STATE_INOCTAL);
  2216. X    }
  2217. X    else if (isspace(c))
  2218. X        return(STATE_SUCCESS);
  2219. X    else
  2220. X        return(STATE_ERROR);
  2221. X}
  2222. X
  2223. X    
  2224. X/****************************************************************************
  2225. X* Append the digit "newNum" onto the right of the number *answer.
  2226. X* Don't allow overflow.  Works for any base.  Return newState on success.
  2227. X****************************************************************************/
  2228. X    
  2229. XSTATE_T IncreaseIfPossible(MIDI_VALUE *answer, int newNum, int base,
  2230. X               STATE_T newState)
  2231. X{
  2232. X    if ((*answer) > (LARGEST_VALUE / base))
  2233. X        return(STATE_OVERFLOW);
  2234. X    else
  2235. X    {
  2236. X        *answer *= base;
  2237. X
  2238. X        if ((*answer) > (LARGEST_VALUE - newNum))
  2239. X            return(STATE_OVERFLOW);
  2240. X        else
  2241. X        {
  2242. X            *answer += newNum;
  2243. X            return(newState);
  2244. X        }
  2245. X    }
  2246. X}
  2247. X
  2248. X
  2249. X/****************************************************************************
  2250. X* Character-oriented routines.
  2251. X****************************************************************************/
  2252. X    
  2253. XSTATE_T DoInChar(int c, MIDI_VALUE *answer)
  2254. X{
  2255. X    if (c == '\\')
  2256. X        return(STATE_BACKSLASHINCHAR);
  2257. X    else
  2258. X    {
  2259. X        *answer = c;
  2260. X        return(STATE_EXPECTQUOTE);
  2261. X    }
  2262. X}
  2263. X
  2264. X    
  2265. XSTATE_T DoExpectQuote(int c, MIDI_VALUE *answer)
  2266. X{
  2267. X    return((c == '\'') ? STATE_SUCCESS : STATE_ERROR);
  2268. X}
  2269. X
  2270. X
  2271. XSTATE_T DoBackslash(int c, MIDI_VALUE *answer, STATE_T newState)
  2272. X{
  2273. X    switch (c)
  2274. X    {
  2275. X        case '0':    *answer = '\0';        break;
  2276. X        case 'a':    *answer = '\a';        break;
  2277. X        case 'b':    *answer = '\b';        break;
  2278. X            case 'f':    *answer = '\f';        break;
  2279. X        case 'n':    *answer = '\n';        break;
  2280. X        case 'r':    *answer = '\r';        break;
  2281. X        case 't':    *answer = '\t';        break;
  2282. X        case 'v':    *answer = '\v';        break;
  2283. X        case '\\':
  2284. X        case '\'':
  2285. X        case '\"':    *answer = c;        break;
  2286. X        default:    return(STATE_ERROR);
  2287. X    }
  2288. X    return(newState);
  2289. X}
  2290. X
  2291. X
  2292. X/****************************************************************************
  2293. X* String-oriented routines.
  2294. X****************************************************************************/
  2295. X    
  2296. XSTATE_T DoInString(int c, STATE_T state, MIDI_VALUE *answer, BOOL *inString)
  2297. X{
  2298. X    switch (state)
  2299. X    {
  2300. X        case STATE_NORMAL:
  2301. X            if (c == '\"')
  2302. X            {
  2303. X                *inString = FALSE;
  2304. X                    return(STATE_NORMAL);
  2305. X            }
  2306. X            else if (c == '\\')
  2307. X                return(STATE_BACKSLASHINSTRING);
  2308. X            else
  2309. X            {
  2310. X                *answer = isspace(c) ? ' ' : c;
  2311. X                return(STATE_SUCCESS);
  2312. X            }
  2313. X            break;
  2314. X        case STATE_BACKSLASHINSTRING:
  2315. X            return(DoBackslash(c, answer, STATE_SUCCESS));
  2316. X    }
  2317. X}
  2318. X
  2319. X
  2320. X/****************************************************************************
  2321. X* Handling comments.  Everything from comment symbol to the end of the
  2322. X* line is a comment.
  2323. X****************************************************************************/
  2324. X
  2325. XSTATE_T DoComment(int c)
  2326. X{
  2327. X    return( (c == '\n') ? STATE_NORMAL : STATE_INCOMMENT );
  2328. X}
  2329. X    
  2330. X/****************************************************************************
  2331. X* Getting help.
  2332. X****************************************************************************/
  2333. X    
  2334. X
  2335. Xvoid InputHelp()
  2336. X{
  2337. X    fprintf(stderr, "INPUT\tMEANING\n"
  2338. X            "1-9...\tDecimal number.\n"
  2339. X            "0...\tOctal number.\n"
  2340. X            "0x...\tHexadecimal number (case-insensitive).\n"
  2341. X            "H...\tHexadecimal number (case-insensitive).\n"
  2342. X            "A-F...\tHexadecimal number (case-insensitive).\n"
  2343. X            "#...\tBinary number.\n"
  2344. X            "'x'\tThe character 'x'."
  2345. X            "  C character syntax like \\n and \\t is valid.\n"
  2346. X            "\"...\"\tA text string."
  2347. X            "  (Newlines turn into space characters.)\n"
  2348. X            "Largest legal input value is %ld (base 10).\n"
  2349. X            "All values must be separated by whitespace.\n\n",
  2350. X        LARGEST_VALUE);
  2351. X}
  2352. X
  2353. X
  2354. X/****************************************************************************
  2355. X* Text output functions.
  2356. X****************************************************************************/
  2357. X    
  2358. Xvoid PrintNumber(MIDI_VALUE number, FILE *out)
  2359. X{
  2360. X    fprintf(out, "Dec %3ld, Oct %3lo, Hex %3lX",
  2361. X        number, number, number);
  2362. X
  2363. X    PrintBinary(number, out);
  2364. X
  2365. X    if (isprint((char)number))
  2366. X        fprintf(out, ", Char '%c'", number);
  2367. X
  2368. X    putc('\n', out);
  2369. X}
  2370. X
  2371. X
  2372. Xvoid PrintBinary(MIDI_VALUE number, FILE *out)
  2373. X{
  2374. X    char buf[BITS_IN_MIDI_VALUE + 1];
  2375. X    int i, on;
  2376. X
  2377. X    for (i=0; i<BITS_IN_MIDI_VALUE; i++)
  2378. X    {
  2379. X        on = number & (1 << i);
  2380. X        buf[BITS_IN_MIDI_VALUE-i-1] = '0' + (char)(on && 1);
  2381. X    }
  2382. X
  2383. X    buf[BITS_IN_MIDI_VALUE] = '\0';
  2384. X    fprintf(out, ", Bin %s", buf);
  2385. X}
  2386. END_OF_FILE
  2387. if test 9628 -ne `wc -c <'Source/text.c'`; then
  2388.     echo shar: \"'Source/text.c'\" unpacked with wrong size!
  2389. fi
  2390. # end of 'Source/text.c'
  2391. fi
  2392. if test -f 'Source/version.h' -a "${1}" != "-c" ; then 
  2393.   echo shar: Will not clobber existing file \"'Source/version.h'\"
  2394. else
  2395. echo shar: Extracting \"'Source/version.h'\" \(628 characters\)
  2396. sed "s/^X//" >'Source/version.h' <<'END_OF_FILE'
  2397. X/**************************************************************************
  2398. X* version.h:    The version number.
  2399. X*        Part of MP, the MIDI Playground.
  2400. X*
  2401. X* Author:    Daniel Barrett
  2402. X* Version:    See the file "version.h".
  2403. X* Copyright:    None!  This program is in the Public Domain.
  2404. X*        Please share it with others.
  2405. X***************************************************************************/
  2406. X
  2407. X    
  2408. X#ifndef _VERSION_H
  2409. X
  2410. X/**************************************************************************
  2411. X* Program version number.
  2412. X**************************************************************************/
  2413. X    
  2414. X#define    VERSION        "1.0"
  2415. X    
  2416. X#endif /* _VERSION_H */
  2417. END_OF_FILE
  2418. if test 628 -ne `wc -c <'Source/version.h'`; then
  2419.     echo shar: \"'Source/version.h'\" unpacked with wrong size!
  2420. fi
  2421. # end of 'Source/version.h'
  2422. fi
  2423. if test -f 'Source/wb.c' -a "${1}" != "-c" ; then 
  2424.   echo shar: Will not clobber existing file \"'Source/wb.c'\"
  2425. else
  2426. echo shar: Extracting \"'Source/wb.c'\" \(86 characters\)
  2427. sed "s/^X//" >'Source/wb.c' <<'END_OF_FILE'
  2428. XBOOL WorkbenchProgram(char *argv[])
  2429. X{
  2430. X    /* For future expansion. */
  2431. X
  2432. X    return(FALSE);
  2433. X}
  2434. END_OF_FILE
  2435. if test 86 -ne `wc -c <'Source/wb.c'`; then
  2436.     echo shar: \"'Source/wb.c'\" unpacked with wrong size!
  2437. fi
  2438. # end of 'Source/wb.c'
  2439. fi
  2440. echo shar: End of archive 1 \(of 2\).
  2441. cp /dev/null ark1isdone
  2442. MISSING=""
  2443. for I in 1 2 ; do
  2444.     if test ! -f ark${I}isdone ; then
  2445.     MISSING="${MISSING} ${I}"
  2446.     fi
  2447. done
  2448. if test "${MISSING}" = "" ; then
  2449.     echo You have unpacked both archives.
  2450.     rm -f ark[1-9]isdone
  2451. else
  2452.     echo You still need to unpack the following archives:
  2453.     echo "        " ${MISSING}
  2454. fi
  2455. ##  End of shell archive.
  2456. exit 0
  2457. -- 
  2458. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  2459. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  2460. Post requests for sources, and general discussion to comp.sys.amiga.misc.
  2461.